NPC Interaction

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:

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:

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:

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.

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.

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.

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'
        }
    }
})