# rep-talkNPC

## INSTALLATION

Download a release [HERE ](https://github.com/BahnMiFPS/rep-talkNPC/releases)or build the source code from [LINK](https://github.com/BahnMiFPS/rep-talkNPC).

> ```
> git clone https://github.com/BahnMiFPS/rep-talkNPC.git
> cd rep-talkNPC/web
> pnpm i
> pnpm build
> ```

Drag and drop the folder into your project and ensure it in your FiveM server.cfg.

## **UI Changes**

* Navigate to the `/web` folder to start modifying the UI.
* Run `pnpm start` in your terminal to launch the UI in your local web environment.
* Post modifications, execute `pnpm build` followed by a script restart in-game to see your changes.

## **Script Usage**

**Examples**

* Refer to `cl_ex.lua` where we've set up a `/testnpc` command enabling you to spawn a sample NPC on your server.
* We have also included the code snippet that we used in the feature video for your future reference.

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

## Exports (Client Side)

> exports\['rep-talkNPC']:CreateNPC(npc, elements)

* npc: `table` (`object`)
  * npc: `string`
  * coords: `vector4`
  * animName, animDist / animScenario: `string`
  * tag: `string`
  * color: `string`
  * startMSG: `string`
  * elements: `table`
    * label: `string`
    * shouldClose: `boolean`
    * action: `function`
    * canInteract: `function`

> exports\['rep-talkNPC']:changeDialog(label, elements)

* label: `string`
* elements: `table`
  * label: `string`
  * shouldClose: `boolean`
  * action: `function`
  * canInteract: `function`

> exports\['rep-talkNPC']:updateMessage(label)

* label: `string`

## TRIGGERS

{% hint style="info" %}
From Client Side :
{% endhint %}

> TriggerEvent('rep-talkNPC:client:close')

{% hint style="info" %}
From Server Side :
{% endhint %}

> TriggerClientEvent('rep-talkNPC:client:close', source)

* This event is used to shut down the dialogue.

## **EXAMPLE : rep-sanitation**

```lua
function talkNPC()
    bossNpc = exports['rep-talkNPC']:CreateNPC({
        npc = "s_m_y_garbage",
        coords = vector4(-351.44, -1566.37, 24.22, 314.22),
        name = 'Brook Stream',
        animScenario = 'WORLD_HUMAN_CLIPBOARD',
        tag ="Sanitation Employees",
        color = "#73583e",
        startMSG = 'Hello, how can I assist you?',
    }, {
        [1] = {
            label ="How does this job work?",
            shouldClose = false,
            action = function()
                exports['rep-talkNPC']:changeDialog("Hello, new here? Let me explain \n \n First, you need a tablet, then apply for a job here. \n \n You can work faster if you work with your friends. You can go 4 and move 2 points at a time. \n \n Oh, little tip, the food at Owo Cafe can help you stay awake to get more tips.",
                    {
                        [1] = {
                            label = "I want to start working",
                            shouldClose = false,
                            action = function()
                                if onDuty == false then
                                    if LocalPlayer.state.nghe == nil or LocalPlayer.state.nghe == "sani" then
                                        exports['rep-talkNPC']:updateMessage(Lang.bossNpc.button1[4])
                                        Wait(1000)
                                        TriggerEvent('rep-talkNPC:client:close')
                                        TriggerEvent('rep-sanitation:client:onDuty')
                                    else
                                        Framework.Notification(Lang.error.own_job.label, Lang.error.own_job.type, Lang.error.own_job.time)
                                    end
                                else
                                    exports['rep-talkNPC']:updateMessage("You already have this job")
                                end
                            end
                        },
                        [2] = {
                            label = "Oh, it doesn't seem to suit me",
                            shouldClose = true,
                            action = function()
                            end
                        }
                    }
                )
            end
        },
        [2] = {
            label = "I want to take the job",
            shouldClose = false,
            action = function()
                if LocalPlayer.state.nghe == nil or LocalPlayer.state.nghe == "sani" then
                    exports['rep-talkNPC']:updateMessage("Now turn on your tablet to find or create a group for yourself!",)
                    TriggerEvent('rep-sanitation:client:onDuty')
                    Wait(2000)
                    TriggerEvent('rep-talkNPC:client:close')
                else
                    Framework.Notification(Lang.error.own_job.label, Lang.error.own_job.type, Lang.error.own_job.time)
                end
            end,
            canInteract = function ()
                if onDuty then
                    return false
                end
                return true
            end
        },
        [3] = {
            label = "I want quit the job",
            shouldClose = false,
            action = function()
                TriggerEvent('rep-sanitation:client:offDuty')
                exports['rep-talkNPC']:updateMessage("It's sad to say goodbye to you")
                Wait(2000)
                TriggerEvent('rep-talkNPC:client:close')
            end,
            canInteract = function ()
                if not onDuty then
                    return false
                end
                return true
            end
        },
        [4] = {
            label = "I want rent a vehicle",
            shouldClose = true,
            action = function()
                if not IsPositionOccupied(Config.Vehicle.spawnpos.x, Config.Vehicle.spawnpos.y, Config.Vehicle.spawnpos.z, 3, false, true, true, false, false, 0, false) then
                    vehSpawnicle()
                else
                    Framework.Notification(Lang.error.occupied.label, Lang.error.occupied.type, Lang.error.occupied.time)
                end
            end,
            canInteract = function()
                local IsGroupLeader = exports['rep-tablet']:IsGroupLeader()
                if onJob and not vehSpawn and IsGroupLeader then
                    return true
                end
                return false
            end
        },
        [5] = {
            label = "I want turn in vehicle",,
            shouldClose = true,
            action = function()
                returnVehicle()
            end,
            canInteract = function()
                local IsGroupLeader = exports['rep-tablet']:IsGroupLeader()
                return doneJob and IsGroupLeader and onJob
            end
        },
        [6] = {
            label = "I want to exchange materials",
            shouldClose = true,
            action = function()
                exchangeSystem()
            end,
            canInteract = function()
              return Config.Exchange.status
            end
        },
        [7] = {
            label = "I'm just passing through here",
            shouldClose = true,
            action = function()
            end
        }
    })
end
```


---

# 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.repscripts.com/free-scripts/quickstart.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.
