# 🗒 MDT
Documentation relating to the jo_mdt.

:::: tabs
::: tab BUY
[Buy the script](https://jumpon-studios.com/redm/sheriff-mdt)
:::

::: tab PREVIEW
<iframe width="560" height="315" src="https://www.youtube.com/embed/gmhL877LsVE?si=Db_h4KODVJHKKhda" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
:::
::::

## 1. Installation
jo_mdt works on all frameworks compatible with jo_libs ([the list](/jo_libs/)).

To install jo_mdt :
- Download the library: [jo_libs](https://github.com/Jump-On-Studios/RedM-jo_libs/releases/latest/download/jo_libs.zip)
- Unzip the folder and drop it in your resource folder
- Download jo_mdt from your [keymaster](https://keymaster.fivem.net/asset-grants?search=mdt)
- Unzip the folder and drop it in your resource folder
- Add this ensure in your server.cfg
  - `ensure jo_libs`
  - `ensure jo_mdt`

Congratulation, the **MDT** script is ready to be used!
:::warning
Be sure you have oxmysql ensure in your server.cfg
:::
:::tip
The script automatically creates all necessary database tables during its initial startup.
:::

:::details For RedEM:RP (old)
Add this Shared functions in `redemrp_inventory/server/sv_main.lua`
```lua:line-numbers=902
  end
  return data
end

function SharedInventoryFunctions.addItemLocker(name, amount, meta, lockerId) -- [!code ++]
  if not Locker[lockerId] then Locker[lockerId] = {} end -- [!code ++]
  return addItemLocker(name, amount, meta, lockerId) -- [!code ++]
end -- [!code ++]
function SharedInventoryFunctions.getLocker(lockerId) -- [!code ++]
  return PrepareToOutput(Locker[lockerId]) -- [!code ++]
end -- [!code ++]

----=======================SHARED FUNCTIONS  ================================
```
:::
:::details For RedEM:RP (2023)
Add this Shared functions in `redemrp_inventory/server/main.lua`
```lua:line-numbers=1558
  end
  return data
end

function SharedInventoryFunctions.addItemStash(source, name, amount, meta, stashId) -- [!code ++]
    if not Stash[stashId] then Stash[stashId] = {} end -- [!code ++]
    addItemStash(source, name, amount, meta, stashId) -- [!code ++]
end -- [!code ++]
function SharedInventoryFunctions.getStash(stashId) -- [!code ++]
    return PrepareToOutput(Stash[stashId]) -- [!code ++]
end -- [!code ++]

RegisterServerEvent("redemrp_inventory:deleteInv",
```
:::

Congratulation, the **MDT** script is ready to be used!

## 2. Usage
- If you set `Config.openingMode = "item"`

Go to one of the sheriff station to get your MDT. Use the MDT item to open it. 

- If you set `Config.openingMode = "command"`

Use `/mdt`to open the MDT

## 3. Script configuration

The configuration file is `config.lua` in the resource root. **Do not edit this file directly** as your changes may be lost during updates. Instead, use `overwriteConfig.lua` to store your customizations.

- **`config.lua`** - Default configuration maintained by developers. **Do not modify this file.**
- **`overwriteConfig.lua`** - This is where you place only the values you want to override.

### How to customize the configuration

1. Open `jo_mdt/overwriteConfig.lua`
2. Find the value you want to change in `config.lua` (e.g., `Config.language`)
3. Copy only that line into `overwriteConfig.lua`
4. Edit the copied value to your liking

The script loads `config.lua` first, then `overwriteConfig.lua` overwrites only the values you redefine. This ensures your customizations are preserved when updating the script.

`jo_mdt/shared/config.lua`

```lua
-------------------------------
-- DOCUMENTATION : https://docs.jumpon-studios.com/
--------------------------------

-------------------------------------------
-- DON'T EDIT THIS FILE
-- TO OVERWRITE CONFIG VALUE, USE overwriteConfig.lua file instead
-------------------------------------------

Config = {}

Config.openingMode = "item"
-- "item": use the item to open the MDT
-- "command": use the command to open the MDT

Config.citizensSyncMode = "global"
-- "station": sync between all MDT from the same station (only if Config.openingMode = "item")
-- "global": sync between all MDT

Config.reportSyncMode = "global"
-- "mdt": only display reports included in the mdt inventory
-- "station": sync between all MDT from the same station (only if Config.openingMode = "item")
-- "global": sync between all MDT

Config.gapWithRealYear = 124 --number of year substract to the real date: 2024 - 124 = 1900

Config.keys = {
  backToClipboard = "INPUT_FRONTEND_UP",
  fileLockerAccess = "INPUT_FRONTEND_ACCEPT",
  getMDT = "INPUT_INTERACT_OPTION1"
}

Config.commands = {
  openMDT = "mdt" --if (Config.openingMode == "command")
}

Config.items = {
  mdt = "mdt", -- MDT item name
  report = "mdt_report", -- report item name
}

Config.stations = {
  {
    id = "saintDenis", --has to be unique
    name = "Saint-Denis",
    location = vec3(2509.532, -1304.805, 48.954),
    distancePrompt = 1.0,
    distanceSync = 2.0,
    jobs = {}
  },
  {
    id = "valentine", --has to be unique
    name = "Valentine",
    location = vec3(-278.373, 803.318, 119.380),
    distancePrompt = 1.0,
    distanceSync = 2.0,
    jobs = {}
  },
  {
    id = "rhodes", --has to be unique
    name = "Rhodes",
    location = vec3(1362.102, -1301.829, 77.765),
    distancePrompt = 1.0,
    distanceSync = 2.0,
    jobs = {}
  },
  {
    id = "strawberry", --has to be unique
    name = "Strawberry",
    location = vec3(-1811.966, -353.963, 164.649),
    distancePrompt = 1.0,
    distanceSync = 2.0,
    jobs = {}
  },
  {
    id = "blackwater", --has to be unique
    name = "Blackwater",
    location = vec3(-761.812, -1272.633, 44.051),
    distancePrompt = 1.0,
    distanceSync = 2.0,
    jobs = {}
  },
  {
    id = "tumbleweed", --has to be unique
    name = "Tumbleweed",
    location = vec3(-5531.495, -2929.364, -1.361),
    distancePrompt = 1.0,
    distanceSync = 2.0,
    jobs = {}
  },
}
```

`jo_mdt/shared/lang.lua`

```lua
-------------------------------------------
-- DON'T EDIT THIS FILE
-- TO TRANSLATE THE SCRIPT, USE overwriteLang.lua file instead
-------------------------------------------

Lang = {}
---@param name string key of the string
---@return string
function __(name) return Lang[name] or ("#"..name) end

-------------
-- PROMPT
-------------
Lang.backToClipboard = "Back to clipboard"
Lang.close = "Close"
Lang.getMDT = "Get a MDT"
Lang.openFileLocker = "Open file locker"

-------------
-- COMMANDS
-------------
Lang.commandOpenMDT = "Open the MDT"

-------------
-- STRINGS
-------------
Lang.fileLocker = "File locker"
Lang.mdt = "MDT"
Lang.mdtDescription  = "MDT from <b>%s</b> station"
Lang.mdtGot = "MDT added in your inventory !"
Lang.reportItemDesc = "Report n°%d<br>%s"

-------------
-- NUI
-------------
Lang.addJail = 'Add jail'
Lang.age = 'Age'
Lang.alias = 'Alias'
Lang.back = 'Back'
Lang.cancel = 'Cancel'
Lang.caseFile = 'Report file'
Lang.citizen = 'Citizen'
Lang.citizenRegisteryNumber = 'Citizen Registry No.'
Lang.citizens = 'Citizens'
Lang.clickToEdit = 'Click to edit'
Lang.confirmSaveCitizen = 'Do you want save this citizen ?'
Lang.confirmSaveReport = 'Do you want save this report ?'
Lang.created = 'Created'
Lang.date = 'Date'
Lang.days = 'Days'
Lang.delete = 'Delete'
Lang.deleteInProgress = 'Delete in progress'
Lang.duration = 'Duration'
Lang.enterImageUrl = 'Enter the image Url'
Lang.enterNameToDelete = 'Enter <b>%s</b> to delete:'
Lang.eyecolor = 'Eye color'
Lang.firstname = 'Firstname'
Lang.formatDate = 'D MMM YYYY, HH:mm'
Lang.haircolor = 'Hair color'
Lang.headerTitle = 'Sheriff Department'
Lang.hours = 'hours'
Lang.id = 'ID'
Lang.incidentReport = 'Incident report'
Lang.inventory = "Inventory"
Lang.jailDuration = 'Jail duration'
Lang.jails = 'Jails'
Lang.jailsHistory = 'Jails history'
Lang.lastname = 'Lastname'
Lang.marks = 'Marks'
Lang.maxInputLength = 'Max length: 255 characters.'
Lang.minutes = 'minutes'
Lang.name = 'Name'
Lang.new = 'New'
Lang.numberJail = 'Number of jail'
Lang.numberReport = 'Number of report'
Lang.refresh = 'Refresh'
Lang.remove = 'Remove'
Lang.report = 'Report'
Lang.reportDeleted = 'Report deleted'
Lang.reportNumber = 'Report No.'
Lang.reports = 'Reports'
Lang.reportsHistory = 'Reports history'
Lang.save = 'Save'
Lang.saveInProgress = 'Save in progress, don\'t close the MDT'
Lang.search = "Search"
Lang.selectJailDuration  = 'Select the jail duration'
Lang.summary = 'Summary'
Lang.title = 'Title'
Lang.unknown = 'Unknown'
Lang.updated = 'Updated'
Lang.warningDelete = 'Warning, you will delete a report.'
Lang.warningDeletePicture = 'Warning, you will delete a picture'
Lang.warningRefresh = 'Warning, all data unsaved will be lost.'
Lang.wrongInput ='Wrong input'
```

## 4. For developers

### Actions

[Actions](/DeveloperResources/actions) are the new way to modify how the script works or add new features. These actions are event that occurs at a specific point in time during the execution of the script. But contrary to events, actions are **synchronous**. 

### Filters

[Filters](/DeveloperResources/filters) are the new way to modify data used by the script added in the `v1.2.0`. These filters are fired at a specific point in time during the execution of the script. But contrary to events, filters are **synchronous**. 

#### `[Client]` canOpenMDT
Fires before open the MDT
```lua
---@param canOpen - boolean
exports.jo_mdt:registerFilter('canOpenMDT', function(canOpen)
	return canOpen
end)
```
#### `[Client]` updateLangForNUI
Fires before update the NUI Lang
```lua
---@param Lang - table: list of lang strings
exports.jo_mdt:registerFilter('updateLangForNUI', function(Lang)
	return Lang
end)
```
#### `[Server]` canGetMDT
Fires before give the MDT to the player
```lua
---@param canGet - boolean
---@param source - integer: server ID of the player
---@param stationKey - integer: key of the station from Config.stations
exports.jo_mdt:registerFilter('canGetMDT', function(canGet,source,stationKey)
	return canGet
end)
```
#### `[Server]` canManageFileLocker
Fires before open the file cabinet
```lua
---@param canManage - boolean
---@param source - integer: server ID of the player
exports.jo_mdt:registerFilter('canManageFileLocker', function(canManage,source)
	return canManage
end)
```
