# NPC Interaction

<figure><img src="/files/DCeXlIcFEbTAKCVhqQMB" alt=""><figcaption></figcaption></figure>

The NPC Interaction module provides a highly immersive, cinematic dialogue system for your server. When a player interacts with an NPC, the script automatically aligns the player, creates a cinematic camera angle focusing on the NPC, and displays a sleek UI for dialogues and options. It fully supports nested submenus, conditional options, and event triggering.

***

### 📚 Available Exports

#### `RegisterNpcInteract`

Registers an interaction menu to a specific NPC entity. This must be called before attempting to show the menu.

Syntax:

```lua
exports['ak47_lib']:RegisterNpcInteract(entity, data)
```

Parameters:

| **Parameter** | **Type**  | **Description**                                                      |
| ------------- | --------- | -------------------------------------------------------------------- |
| `entity`      | `integer` | The network ID or handle of the ped/entity.                          |
| `data`        | `table`   | The configuration object containing dialogues, styling, and options. |

#### `ShowNpcInteract`

Opens a previously registered NPC interaction menu.

Syntax:

```lua
exports['ak47_lib']:ShowNpcInteract(id, focusIndex)
```

Parameters:

| **Parameter** | **Type**             | **Description**                                                 |
| ------------- | -------------------- | --------------------------------------------------------------- |
| `id`          | `string`             | The unique ID defined in your `RegisterNpcInteract` data table. |
| `focusIndex`  | `integer` (Optional) | The index of the option you want to be pre-selected/focused.    |

#### `HideNpcInteract`

Forcefully closes the currently open NPC interaction menu.

Syntax:

```lua
exports['ak47_lib']:HideNpcInteract(runOnExit)
```

Parameters:

| **Parameter** | **Type**  | **Description**                                                            |
| ------------- | --------- | -------------------------------------------------------------------------- |
| `runOnExit`   | `boolean` | If `true`, triggers the `onExit` callback defined in the NPC's data table. |

***

### ⚙️ Configuration Objects

#### The `data` Table

This table configures the overarching menu for the NPC.

| **Property** | **Type**   | **Description**                                                                       |
| ------------ | ---------- | ------------------------------------------------------------------------------------- |
| `id`         | `string`   | Required. A unique identifier for this interaction menu.                              |
| `colors`     | `table`    | Optional. Override default UI colors (`colorPrimary`, `colorSecondary`, `colorText`). |
| `dialogues`  | `table`    | An array of strings. The menu will pick one at random to display as a greeting.       |
| `menu`       | `string`   | Optional. The `id` of a parent menu. Enables native "Back" button functionality.      |
| `onExit`     | `function` | Optional. A callback triggered when the menu is closed.                               |
| `options`    | `table`    | Required. An array of `Option` objects.                                               |

#### The `Option` Object

Each item inside the `options` array represents a clickable button.

| **Property**  | **Type**   | **Description**                                                                |
| ------------- | ---------- | ------------------------------------------------------------------------------ |
| `label`       | `string`   | Required. The text displayed on the button.                                    |
| `icon`        | `string`   | FontAwesome icon name (e.g., `car`, `comments`, `person-walking-arrow-right`). |
| `iconColor`   | `string`   | Hex code to color the icon (e.g., `#3498db`).                                  |
| `isVisible`   | `function` | Returns a boolean. If `false`, the option is completely hidden.                |
| `disabled`    | `boolean`  | If `true`, the option is shown but grayed out/unclickable.                     |
| `canInteract` | `function` | Returns a boolean. Overrides `disabled` dynamically based on logic.            |
| `onSelect`    | `function` | Callback triggered when the player clicks this option.                         |
| `event`       | `string`   | A Client event to trigger when clicked.                                        |
| `serverEvent` | `string`   | A Server event to trigger when clicked.                                        |
| `menu`        | `string`   | Automatically opens another registered NPC menu `id` (acts as a submenu).      |

> Note on Navigation: You can navigate to a submenu using the `menu = 'target_id'` property inside an option, or manually inside the `onSelect` function by calling `exports['ak47_lib']:ShowNpcInteract('target_id')`.

***

### 💡 Examples

#### Example 1: Basic Shop Ped

A simple interaction with a single ped offering basic choices.

```lua
local shopPedId = 0 -- Assuming you have already spawned your ped here

exports['ak47_lib']:RegisterNpcInteract(shopPedId, {
    id = 'hardware_store_main',
    colors = {
        colorPrimary = "rgba(20, 20, 20, 0.95)", 
        colorSecondary = "#ffaa00",
        colorText = "#ffffff",
    },
    dialogues = {
        "Need some tools?",
        "Welcome to the hardware store. What can I get ya?",
        "Make it quick, I'm busy."
    },
    onExit = function()
        print("Player walked away from the hardware store.")
    end,
    options = {
        {
            label = 'Open Shop',
            icon = 'basket-shopping',
            iconColor = '#ffaa00',
            onSelect = function()
                -- Put your shop opening logic here
                TriggerEvent('inventory:client:openShop', 'hardware')
            end
        },
        {
            label = 'Leave',
            icon = 'person-walking-arrow-right',
            iconColor = '#e74c3c'
        }
    }
})

-- To open it (usually triggered via target system like qb-target or ox_target):
-- exports['ak47_lib']:ShowNpcInteract('hardware_store_main')
```

#### Example 2: Dialogue Trees (Submenus & Back Buttons)

This example demonstrates how to create a conversation tree where the player can ask questions, go into a submenu, and hit a "Back" button to return to the main choices.

```lua
local guidePedId = 0 -- Assuming spawned ped

-- 1. Register the Main Menu
exports['ak47_lib']:RegisterNpcInteract(guidePedId, {
    id = 'tour_guide_main',
    dialogues = {
        "Hello traveler! Want to know more about the city?"
    },
    options = {
        {
            label = 'Ask about the City',
            icon = 'city',
            iconColor = '#3498db',
            -- Use the `menu` parameter to automatically link a submenu!
            menu = 'tour_guide_city_info' 
        },
        {
            label = 'Goodbye',
            icon = 'hand-wave',
            iconColor = '#e74c3c'
        }
    }
})

-- 2. Register the Submenu
exports['ak47_lib']:RegisterNpcInteract(guidePedId, {
    id = 'tour_guide_city_info',
    menu = 'tour_guide_main', -- Defining this parent menu enables the native "Back" button
    dialogues = {
        "The city was founded in 1904. We have a rich history!"
    },
    options = {
        {
            label = 'Ask about the Mayor',
            icon = 'user-tie',
            iconColor = '#9b59b6',
            onSelect = function()
                print("The mayor is currently out of town.")
            end
        },
        {
            label = 'Ask about local gangs',
            icon = 'skull',
            iconColor = '#e67e22',
            onSelect = function()
                print("We don't talk about them around here...")
            end
        }
    }
})
```

#### Example 3: Conditional & Restricted Options

Sometimes you only want specific players (like police) to see an option, or you want to show an option but disable it if they don't have enough money.

```lua
local shadyPedId = 0

exports['ak47_lib']:RegisterNpcInteract(shadyPedId, {
    id = 'shady_dealer',
    dialogues = {
        "You got the cash or what?"
    },
    options = {
        {
            label = 'Buy Lockpick ($500)',
            icon = 'key',
            iconColor = '#f1c40f',
            -- Option is visible, but might be disabled
            canInteract = function()
                local hasEnoughMoney = true -- Replace with actual framework money check
                return hasEnoughMoney 
            end,
            onSelect = function()
                TriggerServerEvent('shadydealer:buyLockpick')
            end
        },
        {
            label = '(Police) Confiscate Goods',
            icon = 'shield-halved',
            iconColor = '#3498db',
            -- This completely hides the option if they aren't a cop
            isVisible = function()
                local isCop = false -- Replace with actual framework job check
                return isCop
            end,
            onSelect = function()
                TriggerServerEvent('police:confiscateNPC')
            end
        },
        {
            label = 'Walk away',
            icon = 'person-walking-arrow-right',
            iconColor = '#e74c3c'
        }
    }
})
```


---

# 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://docs.menanak47.com/plugins/ak47_lib/interface/npc-interaction.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.
