# :scissors: NPC Hairs & Beards
Documentation relating to the **jo_hairdresser_npc** add-on for the [Hairdresser script](hairdresser).

:::: tabs
::: tab BUY
[Buy the add-on](https://jumpon-studios.com/redm/hairdresser-npc)
:::
::::

## 1. Installation
::: warning
The [Hairdresser script](hairdresser) is required to use this add-on.
:::

To install jo_hairdresser_npc:
- Drag and drop the resource into your resources folder
  - jo_hairdresser_npc
- Add this ensure to your server.cfg after `ensure jo_hairdresser`
  - `ensure jo_hairdresser_npc`

Congratulations, the **NPC Hairs & Beards** add-on is ready to use!

## 2. Usage

:::: tabs
::: tab Open NPC styles
Go to a hairdresser and open the hairdresser menu.

When the add-on is enabled, compatible hairdresser entries open an intermediate source menu where players can choose between:
- **Natives** - Browse the normal Hairdresser styles
- **NPC** - Browse NPC styles added by the add-on

This intermediate **Natives / NPC** choice appears for:
- **Hair** - Choose between native hair styles and NPC hair styles
- **Beard** - Choose between native beard styles and NPC beard styles

Female characters can also receive a dedicated **Beard** entry when female NPC beard data is available.
:::

::: tab NPC features
In the NPC menus, you can:
- **Browse NPC hair** - Preview and buy NPC hair components
- **Browse NPC beards** - Preview and buy NPC beard components
- **Remove a component** - Select the shaved option to remove the current NPC category
- **Change color presets** - Use the color slider on compatible NPC entries
- **Switch payment options** - Choose between available prices when multiple options exist

Changes are previewed on the player before purchase.
:::

::: tab Supported categories
The add-on includes **668 NPC style choices**:

| Sex | Category | Choices |
| --- | --- | ---: |
| Male | Hair | 339 |
| Male | Full beard | 65 |
| Male | Mustache | 39 |
| Male | Mutton chops | 24 |
| Male | Chin beard | 22 |
| **Male total** |  | **489** |
| Female | Hair | 166 |
| Female | Hair bonnet | 9 |
| Female | Beards | 4 |
| **Female total** |  | **179** |

Available categories depend on the character sex and the enabled prices in the configuration.
:::

::: tab Coloring add-on
If [Hair & Beard Coloring](hairdresser-coloring) is installed and started, compatible NPC components can use the external color palette.

The NPC add-on keeps the purchase flow delegated to the main Hairdresser script, so pricing, payment, persistence, and success feedback stay shared with the normal hairdresser menus.
:::
::::

## 3. Configuration
The configuration files are located in the `config` folder within the resource. This folder contains two subfolders:

- **`_default.lock/`** - Contains the default configuration files. **Do not edit these files directly** as they may be overwritten during updates.
- **`custom/`** - This is where you place your custom configuration files to override the defaults.

### How to customize the configuration

1. Navigate to `jo_hairdresser_npc/config/_default.lock/`
2. Copy the file you want to modify (e.g., `prices.lua`)
3. Paste it into `jo_hairdresser_npc/config/custom/`
4. Edit the copied file in the `custom` folder

The script automatically loads files from `custom/` first, and only uses `_default.lock/` as a fallback. This system ensures your customizations are preserved when updating the script.

### Default configuration files

`jo_hairdresser_npc/config/_default.lock/global.lua`

```lua
-- Use this option with the server filter "canAccessToNPCMenu".
-- The filter receives a context argument:
--   "display": used to decide if NPC entries should be added to Hairdresser menus
--   "open": used when the player clicks an NPC entry and the addon tries to open it
-- "hide_locked": call the filter during "display" and hide NPC entries when access is denied
-- "show_locked": keep NPC entries visible and call the filter only on "open"
Config.npcMenuAccessMode = "hide_locked"
```

`jo_hairdresser_npc/config/_default.lock/lang.lua`

```lua
Lang.value = "value"
Lang.npc = "NPC"
Lang.number = "Number %d"
Lang.coloring = "Coloring"

Lang.npcDesc = "Browse NPC hair and beard styles"

Lang.beards = "Beards"
Lang.beards_chin = "Chin Beard"
Lang.beards_chops = "Mutton Chops"
Lang.beards_complete = "Full Beard"
Lang.beards_mustache = "Mustache"
Lang.hair_bonnet = "Hair Bonnet"
```

`jo_hairdresser_npc/config/_default.lock/prices.lua`

```lua
-- ================================================================
-- PRICE CONFIGURATION GUIDE
-- ================================================================
-- Need to build or adjust a price table quickly?
-- Use the official Price Generator here:
--   https://docs.jumpon-studios.com/DeveloperResources/price-generator
--
-- The generator creates ready-to-paste Lua price tables for this config.
-- Copy the generated Lua code and paste it as the value of the relevant
-- price entry or model override.
-- ================================================================

Config.prices = { --Use false to turn off the submenu
    beards = {
        operator = "or",
        { money = 3.75 },
        { gold = 1 },
    },
    beards_chin = {
        operator = "or",
        { money = 18 },
        { gold = 3 },
    },
    beards_chops = 1.0,
    beards_mustache = 5,
    hair_bonnet = {
        operator = "or",
        { money = 3.75 },
        { gold = 1 },
    },
}

Config.modelPrices = {}           --Override prices for specific clothing models

Config.modelPrices["male"] = {}   --Male-specific model price overrides

Config.modelPrices["female"] = {} --Female-specific model price overrides
for category in pairs(Config.prices) do
    Config.modelPrices["male"][category] = {}
    Config.modelPrices["female"][category] = {}
end

Config.modelPrices["male"]["beards_chops"][2] = { gold = 1000 }

-- Config.modelPrices.male.beards_chops[3] = -1 -- Disable male beardschops model 3

-- Model-specific price examples:
-- Config.modelPrices["male"]["beards_chin"][2] = { gold = 10 } -- Male chin beard model 2 costs 10 gold
-- Config.modelPrices.male.beards_mustache[4] = 10              -- Male mustache model 4 costs $10
-- Config.modelPrices.female.hair_bonnet[1] = -1                -- Disable female hair bonnet model 1
-- Config.modelPrices.female.beards[2] = { money = 8 }          -- Female beard model 2 costs $8

-- Known bugged NPC models:
-- Config.modelPrices.male.beards_chops[55] = -1                -- Disable male chops model 55
```

## 4. For developers

### Filters

[Filters](/DeveloperResources/filters) allow you to modify data or permissions synchronously at specific points in the script.

#### `[Server]` canAccessToNPCMenu
Control access to the NPC hair and beard menus.

This filter works with `Config.npcMenuAccessMode`.

- `hide_locked` - the filter is called with the `display` context. When it returns `false`, the add-on stays linked to Hairdresser but does not add its NPC entries to the menu. Players will see the same behavior as if the NPC add-on was not present: Hair and Beard open the native Hairdresser menus directly.
- `show_locked` - NPC entries stay visible. The filter is called only with the `open` context when the player clicks an NPC entry. Return `false` to block the menu opening and optionally notify the player.

Available contexts:

- `display` - checks if NPC entries should be added to the Hairdresser menus.
- `open` - checks if the NPC menu can open after the player clicks an NPC entry.

```lua
-- @param canAccess - boolean (default true)
-- @param source - serverID of the player
-- @param context - string ("display" or "open")
exports.jo_hairdresser_npc:registerFilter("canAccessToNPCMenu", function(canAccess, source, context)
    return canAccess
end)
```

Example - allow only VIP players:

```lua
local vipPlayers = {}

exports.jo_hairdresser_npc:registerFilter("canAccessToNPCMenu", function(canAccess, source, context)
    return canAccess and vipPlayers[source] == true
end)
```

Example - keep NPC entries visible and notify only when the player clicks:

```lua
-- config/_default.lock/global.lua or your custom config file
Config.npcMenuAccessMode = "show_locked"
```

```lua
local isSubscriber = false

exports.jo_hairdresser_npc:registerFilter("canAccessToNPCMenu", function(canAccess, source, context)
    if context == "open" and not isSubscriber then
        jo.notif.rightError(source, "You can't access the NPC menu if you're not a subscriber")
    end

    return canAccess and isSubscriber
end)
```
