> For the complete documentation index, see [llms.txt](https://wiki.qfdevelopers.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.qfdevelopers.com/scripts/editor-4/configuration.md).

# Configuration

## Languages

You can set the language of the script in the configuration file.

* `en-US`: English
* `fr-FR`: French
* `pl-PL`: Polish
* `de-DE`: German
* `es-ES`: Spanish
* `pt-PT`: Portugese
* `ja-JP`: Japanese
* `es-IT`: Italian
* `ko-KR`: Korean

```lua
Config.Locale = "en-US"
```

### Commands & Keybinds <a href="#user-content-commands-keybinds" id="user-content-commands-keybinds"></a>

**General**

* `/mdtlspd` (DELETE): Toggle the MDT Dashboard.
* `/qfmdtbadge` (B): Show/Hide Officer Badge.

**Camera Mode**

* `/qfmdtpolicecapturephoto` (ENTER / SPACE): Take a photo.
* `/qfmdtpolicecameratogglefocus` (L-ALT / RMB): Toggle mouse focus.
* `/qfmdtpolicecameratoggleflashlight` (F): Toggle camera flashlight.
* `/qfmdtpolicecameratoggleside` (R): Switch between Front/Back camera.

**Radar**

* `/qfmdtradartoggle` (U): Toggle the entire Radar system.
* **Front Radar Settings**
  * `/qfmdtradarshowfront` (F5): Show Front Radar.
  * `/qfmdtradarhidefront` (F6): Hide Front Radar
  * `/qfmdtradartoggleinteractfront` (PGUP): Lock/Unlock Front Radar target
* **Back Radar Settings**
  * `/qfmdtradarshowback` (F7): Show Back Radar.
  * `/qfmdtradarhideback` (F8): Hide Back Radar
  * `/qfmdtradartoggleinteractback` (PGDN): Lock/Unlock Back Radar target

{% hint style="info" %} <mark style="color:$info;">**Note:**</mark> <mark style="color:$info;"></mark><mark style="color:$info;">All keys are configurable in config.lua.</mark>
{% endhint %}

#### 1. Configuring Ranks (Grades) <a href="#user-content-1-configuring-ranks-grades" id="user-content-1-configuring-ranks-grades"></a>

In config.lua, the `Config.Grades` table controls the hierarchy visible in the MDT. This **must** match your framework's job grades (ESX/QBCore/QBOX) to ensure correct label display.

```lua
-- config.lua
Config.Grades = {    
    {id = 0, name = "Cadet"},     
    {id = 1, name = "Officer I"},    
    {id = 2, name = "Officer II"},    
    {id = 3, name = "Sergeant"},    
    {id = 4, name = "Lieutenant"},    
    {id = 5, name = "Chief"}
}
-- Ensure 'id' corresponds to the grade integer in your database.
```

#### 2. Customizing Fines <a href="#user-content-2-customizing-fines" id="user-content-2-customizing-fines"></a>

You can add new categories and fines in `Config.FineList`.

```lua
-- config.lua
Config.FineList = {    
    {        
        id = "1", -- Unique Category ID        
        label = "Traffic Laws",        
        items = {            
            {                    
                id = "1",                 
                label = "Speeding (> 50 km/h)",                 
                fine = 500,                 
                jail = 0 -- Optional: Jail time in months/minutes            
            },            
            {                
                id = "2",                 
                label = "Reckless Driving",                 
                fine = 1000,                 
                jail = 5            
            }        
        }    
    }
}
```

#### 3. Dispatch Colors & Vehicles <a href="#user-content-3-dispatch-colors--vehicles" id="user-content-3-dispatch-colors--vehicles"></a>

The dispatch system uses specific color codes for vehicles. These are defined in `Config.Dispatch.Colors`. When creating custom alerts, you can use these or standard RGB values.

***

### Server-side Exports <a href="#user-content-server-side-exports" id="user-content-server-side-exports"></a>

Use these exports in your other resources to interact with the MDT backend.

#### `AddLog` <a href="#user-content-addlog" id="user-content-addlog"></a>

Adds an entry to the Audit Log. Useful for tracking evidence locker access, armory usage, or boss menu actions.

**Syntax:**

```lua
exports.qf_mdt_police_v2:AddLog(source, tag, text, color, fields, args)
```

**Parameters:**

| Parameter | Type   | Description                                                     |
| --------- | ------ | --------------------------------------------------------------- |
| `source`  | number | Player Source ID.                                               |
| `tag`     | string | Category tag (e.g., 'armory', 'evidence', 'boss').              |
| `text`    | string | Log message.                                                    |
| `color`   | string | Color theme ('blue', 'red', 'green', 'orange').                 |
| `fields`  | table  | (Optional) Key-value pairs for extra metadata.                  |
| `args`    | table  | (Optional) Arguments for translation if `text` is a locale key. |

**Example (Armory Usage):**

```lua
-- Triggered when a player withdraws a weapon
local weaponName = "WEAPON_PISTOL"
local ammoCount = 50

exports.qf_mdt_police_v2:AddLog(    
    source,     
    "armory",     
    "Withdrew weapon from armory",     
    "red",     
    {         
        weapon = weaponName,         
        ammo = ammoCount,        
        serialNumber = "WX-12345"     
    }
)
```

***

### Client-side Exports <a href="#user-content--client-side-exports" id="user-content--client-side-exports"></a>

Use these exports to integrate the MDT UI and systems with other scripts (e.g., Robbery scripts, Radar systems).

#### `CreateDispatchAlert` <a href="#user-content-createdispatchalert" id="user-content-createdispatchalert"></a>

Triggers a dispatch notification for all on-duty police.

**Syntax:**

```lua
exports.qf_mdt_police_v2:CreateDispatchAlert(coords, title, description, code, colorRGB, maxOfficers, duration)
```

**Parameters:**

| Parameter     | Type    | Description                                      |
| ------------- | ------- | ------------------------------------------------ |
| `coords`      | vector3 | Location of the alert.                           |
| `title`       | string  | Alert Header.                                    |
| `description` | string  | Detailed info (e.g., street name, vehicle info). |
| `code`        | string  | 10-Code (e.g., '10-90').                         |
| `colorRGB`    | table   | `{r, g, b}` format.                              |
| `maxOfficers` | number  | (Optional) flashing limit of units.              |
| `duration`    | number  | (Optional) Time in ms the alert stays on screen. |

**Example (Bank Robbery):**

```lua
-- Triggered when a player starts hacking a vault
local plyPed = PlayerPedId()
local coords = GetEntityCoords(plyPed)
local streetName = GetStreetNameFromHashKey(GetStreetNameAtCoord(coords.x, coords.y, coords.z))

exports.qf_mdt_police_v2:CreateDispatchAlert(
    coords,    
    "Bank Robbery in Progress",    
    "Silent alarm triggered at " .. streetName .. " Fleeca Bank.",    
    "10-90",    
    {255, 0, 0}, 
    15, 
    10000
)
```

#### `showOfficerBadge` <a href="#user-content-showofficerbadge" id="user-content-showofficerbadge"></a>

Displays the badge ID card on screen.

**Syntax:**

```lua
exports.qf_mdt_police_v2:showOfficerBadge(data)
```

**Data Structure:**

```lua
{    
    name = "Officer Name",    
    badge = "Badge Number",    
    gradeLabel = "Rank Name",    
    mugshot = "URL to image (optional)",    
    licenses = {        
        { label = "Weapon License", active = true },        
        { label = "Driving License", active = false }    
    }
}
```

**Example:**

```lua
exports.qf_mdt_police_v2:showOfficerBadge(
{    
    name = "Robert Smith",    
    badge = "9921",    
    gradeLabel = "Chief of Police",    
    licenses = {        
        { label = "Advanced Driving", active = true },        
        { label = "SWAT Tactics", active = true }    
    }
})
```

#### `AddHeistZone` (Map) <a href="#user-content-addheistzone-map" id="user-content-addheistzone-map"></a>

Adds a visual zone to the live map, useful for ongoing robberies.

**Syntax:**

```lua
exports.qf_mdt_police_v2:AddHeistZone(zoneData)
```

**Example:**

```lua
exports.qf_mdt_police_v2:AddHeistZone({    
    id = "pacific_standard",    
    name = "Pacific Standard Robbery",    
    position = { x = 255.2, y = 210.0 }, 
    radius = 60.0,    street = "Vinewood Blvd",    
    thumbnailUrl = "https://example.com/bank-image.jpg"
})
```

#### `RemoveHeistZone` <a href="#user-content-removeheistzone" id="user-content-removeheistzone"></a>

Removes a heist zone when the event is over.

**Example:**

```lua
exports.qf_mdt_police_v2:RemoveHeistZone("pacific_standard")
```

***

### Camera & Radar Exports <a href="#user-content--camera--radar-exports" id="user-content--camera--radar-exports"></a>

#### Bodycam <a href="#user-content-bodycam" id="user-content-bodycam"></a>

Control the immersion overlays.

```lua
exports.qf_mdt_police_v2:showBodycam()

exports.qf_mdt_police_v2:hideBodycam()
```

#### Radar <a href="#user-content-radar" id="user-content-radar"></a>

Control the vehicle radar system programmatically.

```lua
-- Force show front radar
exports.qf_mdt_police_v2:showRadar("front") 

-- Manually update radar data (e.g. for a tutorial or scripted event)
exports.qf_mdt_police_v2:setRadarData("front", {    
    plate = "FAKE-123",    model = "Buffalo",    speed = 150,    speedDisplay = "km/h"
})
```

### Dispatch Integrations & Custom Alerts

#### Compatibility

Enable 3rd party script compatibility by editing `config/config.lua`.

```lua
-- Enable external dispatch scripts in config/config.lua
Config.Dispatch = {
    Integration = {
        rcore_dispatch = true, -- Set to true to automatically bridge alerts
        core_dispatch = false,
        opto_dispatch = false,
        tk_dispatch = false
    }
}
```

#### Custom Alerts

Control and send dispatch alerts to the MDT programmatically.

```lua
-- Send a custom dispatch alert manually from any server script
TriggerEvent('qf_mdt_police_v2/server/addCustomDispatch', {
    id = "custom_robbery_123",        -- (Optional) Unique ID, system generates one if empty
    title = "Store Robbery",          -- Alert title/name
    code = "10-90",                   -- Dispatch code
    color = {255, 0, 0},              -- RGB color table or HEX string (e.g., "#FF0000")
    street = "Route 68",              -- (Optional) Street name or location description
    x = 100.5,                        -- X coordinate of the alert
    y = -213.2,                       -- Y coordinate of the alert
    z = 32.5,                         -- Z coordinate of the alert
    max_officers = 6,                 -- (Optional) Maximum officers that can react (default: 10)
    duration = 5000                   -- (Optional) Duration the alert stays on screen in ms (default: 5000)
})
```

#### 1. Client-Side Export <a href="#user-content-1-client-side-export" id="user-content-1-client-side-export"></a>

You can use the following export directly in any client-side script.

```lua
-- @param coords vector3 - The coordinates of the incident
-- @param title string - The title of the dispatch alert
-- @param description string - The detailed description
-- @param code string - The dispatch code (e.g., "10-13")
-- @param colorRGB table - An array containing RGB values (e.g., { 251, 45, 55 })
-- @param maxOfficers number - Maximum number of officers that can respond (e.g., 10)
-- @param duration number - The duration the alert shows on screen in milliseconds (e.g., 5000)

local coords = GetEntityCoords(PlayerPedId())
exports['qf_mdt_police_v2']:CreateDispatchAlert(    
    coords,     
    "Officer Down",     
    "An officer has been injured and requires immediate assistance.",     
    "10-13",     
    { 251, 45, 55 },     
    10,     
    5000
)
```

#### 2. Server-Side Event (or Client `TriggerServerEvent`) <a href="#user-content-2-server-side-event-or-client-triggerserverevent" id="user-content-2-server-side-event-or-client-triggerserverevent"></a>

If you need to trigger a dispatch from the server, or prefer passing a data table, you can use the built-in server event.

```lua
local dispatchData = {    
    x = 100.0,           -- [Required] Coordinate X    
    y = -200.0,          -- [Required] Coordinate Y    
    z = 30.0,            -- [Required] Coordinate Z    
    title = "Robbery",   -- [Required] Dispatch Title    
    code = "10-90",      -- [Required] Dispatch Code        
    color = {255, 0, 0}, -- [Optional] RGB table or HEX string (e.g., "#FF0000"). Defaults to blue.    
    street = "Route 68", -- [Optional] Street name. Defaults to empty.    max_officers = 10,   -- [Optional] Maximum responding officers. Defaults to 10.    
    duration = 5000,     -- [Optional] Screen duration in ms. Defaults to 5000.    
    id = "custom_id_1"   -- [Optional] A custom unique ID if you need to manage it later
}

-- If triggering from a SERVER script:
TriggerEvent('qf_mdt_police_v2/server/addCustomDispatch', dispatchData)

-- If triggering from a CLIENT script:
TriggerServerEvent('qf_mdt_police_v2/server/addCustomDispatch', dispatchData)
```

## Resetting Officer Hours <a href="#user-content-4-resetting-officer-hours-police" id="user-content-4-resetting-officer-hours-police"></a>

The Police MDT tracks on-duty hours for all officers. These hours can be manually reset via a server callback. The system verifies if the player executing the reset has the appropriate job permissions defined in `Config.Jobs`.

* **Callback Name:** `qf_mdt_police_v2/resetOfficerHours`
* **Target Identifier:** `id` (Character Identifier / CitizenID / License)

**Code Example**

```lua
local officerId = "POLICE_001"

CALLBACK.TriggerServerCallback('qf_mdt_police_v2/resetOfficerHours', function(result)    
    if result.success then        
        print("Officer hours have been reset successfully.")    
    else        
        print("Error: " .. result.error)    
    end
end, officerId)
```

## Duty Status Change Hook <a href="#user-content-6-duty-status-change-hook-police" id="user-content-6-duty-status-change-hook-police"></a>

We have added a server-side hook that triggers whenever an officer changes their duty status via the MDT (e.g., clicking "Available" or "Unavailable"). This is useful for synchronizing the MDT state with other job-related systems or triggering custom events.

* **Location:** `config/server/editable.lua`
* **Function:** `EDITABLE.OnStatusChange(source, status)`

**Usage Example**

This hook is defined in the editable configuration file and can be used to trigger framework-specific duty events:

```lua
function EDITABLE.OnStatusChange(source, status)
    -- Triggered for status: "available", "unavailable"
    
    if status == "available" then
        -- Example: Triggering a custom onDuty event
        TriggerEvent('examplepolicejob:onDuty', source)
    elseif status == "unavailable" then
        -- Example: Triggering a custom offDuty event
        TriggerEvent('examplepolicejob:offDuty', source)
    end
end
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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://wiki.qfdevelopers.com/scripts/editor-4/configuration.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.
