> For the complete documentation index, see [llms.txt](https://malbersanimations.gitbook.io/animal-controller/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://malbersanimations.gitbook.io/animal-controller/super-item/super-item-system/super-item-manager/holsters.md).

# Holsters

## Overview

A **Holster** is where an item rests when it is owned but not in the character's hands — a scabbard on the hip, a quiver on the back, a pistol on the thigh. It pairs a `HolsterID` asset with one or more **Slot** Transforms, and tracks every item currently stored in it.

The Holster ID does double duty: it identifies the storage location, **and** it becomes the ability index of the draw/store Mode, which is how one `Weapon Draw` Mode plays the correct animation for every holster on the body.

Holsters live on the **Holsters** tab of the Super Item Manager.

***

## Requirements

* A `HolsterID` asset. `Left Holster` and `Right Holster` are created by `Reset`.
* At least one **Slot** Transform, parented to the bone the item should rest on.
* Items whose `Holster` — or `Secondary Holster` — field matches the ID.

***

## How it works

### Storing

`Item_Holster(item)` finds the holster whose ID matches the item's `Holster`, then:

1. unequips the item instantly if it was held,
2. resolves a **slot** from the item's authored **Holster Slots** priority list in the Item Offsets asset,
3. parents the item to that slot Transform and applies the holster offset for this **(Item Type + Holster)** pair,
4. disables the item's physics, sets `Is In Holster`, and fires `On Item Holster Enter`.

### Resolving the slot

The authored list wins, in order. The **first** index in it that exists on this holster and is still free is taken — `[0, 2]` sends the first dagger to slot `0` and the second to slot `2`. Only when every authored slot is occupied does the holster scan the rest of its Slots list, wrapping around from the preferred one.

If nothing is free anywhere and the item declares a **Secondary Holster**, the copy falls through to that holster instead, where it gets its own Offset, Slots and Holster Anim entry. That is how a second dagger ends up on the other hip rather than pushing the first one out.

When there is genuinely nowhere left, the **oldest** stored item is evicted, properly dropped (unparented, with its physics restored) and a warning tells you to add more slots.

{% hint style="info" %}
**Swapping is slot-preserving.** An item being drawn out of a holster still hangs in its slot while the Equip animation plays, but its slot already counts as free — so the item holstered in exchange (stored immediately, before the draw finishes) takes that very slot instead of being bumped elsewhere. If the draw is cancelled, the item simply keeps its slot.
{% endhint %}

{% hint style="info" %}
A **prefab** assigned to a holster at edit time is instantiated the first time it is stored, so you can author "the character starts with a spare sword on their back" without putting an instance in the scene.
{% endhint %}

### Drawing

Pressing the holster's `Input` calls `Item_Equip_From_Holster(id)`:

* **The holster has items** — *every* item stored in it is drawn. This matters for dual wielding, where two swords share one holster.
* **The holster is empty** and `Self Store Holster` is on — every equipped item whose `Holster` ID matches is stored instead. The same key toggles draw and store.

### The draw animation

The ability index passed to the Equip / Unequip Mode is:

```
ability = Holster Anim ID (or the item's Holster ID when no override exists)
ability *= (side == Left) ? +1 : -1
```

So the Mode transition conditions can distinguish "draw the left-hip sword with the right hand" from "draw the back axe with the left hand" using a single signed integer. The `Holster Anim` override lives per item in the Item Offsets asset, so one holster can play different animations for different items.

***

## Properties

### Holster entry

#### ID

The `HolsterID` asset. Items with a matching `Holster` field are stored here.

#### Item

The item currently stored — the **head** of the holster, meaning the most recently stored one. Assign one at edit time to have the character start with it. A prefab is instantiated on first use.

#### Slots

The list of Transforms items are parented to. A holster with three slots can hold three items.

Which slots a given item prefers, and in what order, is authored per item in the `SuperItemOffsets` asset (the **Holster Slots** list of the Holster Offsets table), not here.

#### Input

The input name that draws from — or stores into — this holster. Connected on `OnEnable`, disconnected on `OnDisable`.

#### Auto Equip

When an item is added to this holster, equip it to the hand immediately instead of leaving it stored.

***

## The Holster ID asset

`HolsterID` is a plain Malbers `IDs` asset: an auto-assigned unique integer and a name. Create one with `Assets ▸ Create ▸ Malbers Animations ▸ ID ▸ Holster ID`.

{% hint style="warning" %}
Duplicated ID **values** break the lookup — the Manager builds a dictionary keyed by ID on `Awake`. When you duplicate a holster asset, make sure the integer is regenerated (right-click ▸ *Get ID*).
{% endhint %}

***

## Events

Per holster:

| Event                                   | Fires when                                                           |
| --------------------------------------- | -------------------------------------------------------------------- |
| **On Item Holster Enter** (`SuperItem`) | An item is stored in this holster.                                   |
| **On Item Holster Exit** (`SuperItem`)  | An item leaves this holster — drawn, dropped, or evicted by another. |

The item itself also fires `On Holstered` and `On Unholstered`, sending the character's GameObject.

***

## Debug

With the **Holsters** tab selected, the Scene View draws the assigned item's Display Mesh at each slot, at the exact transform it will have at runtime, with a cube tinted by the item's `Holster Color` (or red when the item's Holster ID does not match). Position, rotation and scale handles write the offset into the asset as you drag — there is no Save button.

The Manager's **Debug** toggle prints holster and unholster events with the resolved slot index.

***

## API

```csharp
SItemHolster holster = manager.D_Holsters[holsterID];

holster.HasItem;                 // is anything stored
holster.Item;                    // the most recently stored item (the head)
holster.Contains(item);          // is this specific item stored here
holster.HasRoomFor(item);        // is one of the item's authored slots still free
holster.GetUsedSlot(item);       // which slot index it occupies
holster.GetSlotPriority(item);   // the authored slot priority list
holster.GetSlot(index);          // the slot Transform
holster.Holster(item);           // store
holster.Holster(item, out var evicted);  // store, and learn who was pushed out
holster.Clear(item);             // remove one item; the previous one is promoted to head
```

***

## See also
