# esx_accessorymanager (/docs/addons/esx_accessorymanager)

esx_accessorymanager is a client-only radial menu that lets players take off and put back the clothing and props they are currently wearing: hat, glasses, mask, watch, top, pants, shoes and more. Use it when you want a quick wardrobe toggle (for example "take off mask") without building outfits or shops.

<Callout type="info" title="Not in the official docs">
This addon is not covered on docs.esx-framework.org. Everything below is taken from the resource source.
</Callout>

## Overview [#overview]

| | |
|---|---|
| Resource | `esx_accessorymanager` |
| Side | Client only (NUI) |
| Dependencies | `esx_lib`, `es_extended`, `skinchanger` |
| Database | None |
| Open with | `F11` key mapping or `/accessories` |
| Supported peds | `mp_m_freemode_01` and `mp_f_freemode_01` only |

The radial menu has 13 sectors: watch, glasses, mask, necklace, earrings, pants, shoes, top (with arms), hat, bag, undershirt, bracelet and vest. The center button restores everything removed by this resource. Two extra tools are available:

- **Fix accessories** reapplies all current props from the skin, useful when a hat or glasses visually disappear.
- **Fix hair** toggles the hairstyle to drawable `0` (for example to hide hair under a helmet) and back to the saved hairstyle and colors.

Removing a vest only hides the drawable. It does not change gameplay armor.

The menu refuses to open (or closes itself) while the player is dead, ragdolling, falling, cuffed, in the pause menu, has `LocalPlayer.state.invBusy` set, already has NUI focus, or sits in a vehicle (unless allowed).

## Installation [#installation]

No SQL file. Start it after its dependencies:

```bash title="server.cfg"
ensure esx_lib
ensure es_extended
ensure skinchanger
ensure esx_accessorymanager
```

The NUI ships prebuilt in `html/`, there is no build step.

## Configuration [#configuration]

All keys live in `config.lua`.

| Key | Default | Description |
|---|---|---|
| `Config.Locale` | `GetConvar('esx:locale', 'en')` | Locale for labels. English and Spanish are included; missing keys fall back to English. |
| `Config.EnableControls` | `true` | Registers the `accessorymanager` key mapping. The `/accessories` command exists either way. |
| `Config.Radial.Command` | `'accessories'` | Chat command that toggles the menu. |
| `Config.Radial.DefaultKey` | `'F11'` | Default key of the key mapping. Players can rebind it in the FiveM settings. |
| `Config.Radial.ActionCooldown` | `350` | Minimum milliseconds between two wardrobe actions. |
| `Config.Radial.AllowInVehicle` | `false` | Allow opening the menu inside a vehicle. |
| `Config.Radial.Undressed.male` | `{ tshirt = 15, torso = 15, arms = 15, pants = 61, shoes = 34 }` | Drawables used when a male freemode ped takes off these items. |
| `Config.Radial.Undressed.female` | `{ tshirt = 15, torso = 15, arms = 15, pants = 15, shoes = 35 }` | Same for the female freemode ped. |
| `Config.Radial.Animation.Enabled` | `true` | Play a clothing animation before each change. |
| `Config.Radial.Animation.Timeout` | `500` | Milliseconds to wait for the animation dictionary to load before skipping the animation. |
| `Config.Radial.Animation.Duration` | `900` | Fallback animation length in milliseconds. |
| `Config.Radial.Animation.Flag` | `49` | Fallback animation flag. |
| `Config.Radial.Animation.Default` | `{ dict = 'clothingshirt', anim = 'try_shirt_positive_d' }` | Animation for categories without an own entry (`tshirt`). |
| `Config.Radial.Animation.ByCategory` | per category | Per category `{ dict, anim, flag, duration }`. `helmet` uses separate `on` and `off` clips. `repairHair` is used by the Fix hair button. |

Items other than tops, undershirts, pants and shoes are removed by setting drawable `0` (components) or clearing the prop (`-1`). If you run a custom clothing pack where `15`, `61` or `34` are real clothes, adjust `Undressed`.

## Client exports [#client-exports]

### OpenAccessoryMenu [#openaccessorymenu]

```lua
exports.esx_accessorymanager:OpenAccessoryMenu()
```

Opens the radial menu. If it is already open, the call closes it (toggle). Does nothing when the player cannot use the menu right now.

### CloseAccessoryMenu [#closeaccessorymenu]

```lua
exports.esx_accessorymanager:CloseAccessoryMenu()
```

Closes the menu and releases NUI focus.

### InvalidateWardrobe [#invalidatewardrobe]

```lua
exports.esx_accessorymanager:InvalidateWardrobe()
```

Forgets all items removed by the menu and the Fix hair state. Call it after your own script changes the outfit without going through `skinchanger:loadSkin` or `skinchanger:loadClothes` (those two events already invalidate automatically).

Example: open the wardrobe from a radial or target menu of another resource.

```lua title="client/main.lua"
RegisterCommand('wardrobe', function()
    if GetResourceState('esx_accessorymanager') ~= 'started' then return end
    exports.esx_accessorymanager:OpenAccessoryMenu()
end, false)
```

## Client events [#client-events]

| Event | Type | Description |
|---|---|---|
| `esx_accessorymanager:openMenu` | Local event | Same as the `OpenAccessoryMenu` export. Use `TriggerEvent`, it is not a network event. |

The resource listens to `esx:playerLoaded` and `esx:onPlayerLogout` (clears state), `esx:onPlayerDeath` (closes the menu) and the skinchanger load events. When the resource stops, it restores every removed item if `skinchanger` is still running.

## Security notes [#security-notes]

The NUI only sends an action id (max 32 characters) from a fixed allowlist. Drawables, textures and models are never taken from the UI; every value is validated against the active ped with `IsPedComponentVariationValid` and the prop variation natives. There are no server events, so the resource cannot be abused to give items or money.

## Integration tips [#integration-tips]

- **esx_accessories:** both can run together. esx_accessories sells and saves items; esx_accessorymanager only toggles what is worn.
- **Inventories:** set `LocalPlayer.state.invBusy = true` while your inventory is open to block the radial menu.
- **Custom skin scripts:** if you apply clothes without skinchanger, call `InvalidateWardrobe` afterwards so "restore" does not bring back old items.

## Common issues [#common-issues]

- **"This character model is not supported."** The player uses an addon or story ped. Only the two freemode models are supported.
- **Item greyed out.** The item is already in its "off" state, or the off values from `Undressed` are not valid for the ped.
- **F11 conflicts with another script.** Change `Config.Radial.DefaultKey`. Existing players keep their old binding until they rebind it, because FiveM stores key mappings per client.

## Related [#related]

- [esx_accessories](/docs/addons/esx_accessories)
- [skinchanger](/docs/core/skinchanger)
- [esx_skin](/docs/core/esx_skin)
- [esx_lib](/docs/core/esx_lib)
