Skip to main content

🧩 EditTable β€” Complete Reference

The EditTable is the heart of XR-MDT customization. It is a globally accessible Lua table that exposes every integration point the script offers β€” from money handling and database queries to dispatch routing and job-specific logic. Because XR-MDT is Tebex Escrow-protected, you cannot modify core files β€” but you can modify everything inside the editable/ folder, and the EditTable is the bridge that connects your custom code to the protected core.

πŸ“– What is the EditTable?

ConceptExplanation
PurposeA global Lua table (EditTable) that holds all editable functions, events, and queries the MDT core calls at runtime.
LocationDefined across files in editable/server/ and editable/client/.
How it worksThe core (escrowed) code calls EditTable.Events.RemoveMoney(...) instead of directly calling a framework function. You control what happens inside that function.
SafetyModifying EditTable functions never breaks escrow β€” the core only reads from it.
[!IMPORTANT] Every EditTable function listed below is fully editable. Override any of them to adapt XR-MDT to your server’s custom scripts, frameworks, or databases.

πŸ“ File Structure

editable/
β”œβ”€β”€ server/
β”‚   β”œβ”€β”€ main.lua          ← Core bridge, Bridge functions, framework detection, EditTable.Events
β”‚   β”œβ”€β”€ lspd.lua          ← Police-specific events, queries, helpers
β”‚   β”œβ”€β”€ ems.lua           ← EMS-specific events and queries
β”‚   β”œβ”€β”€ doj.lua           ← DOJ/Court events and queries
β”‚   β”œβ”€β”€ business.lua      ← Business management events, queries, finance
β”‚   β”œβ”€β”€ sv_items.lua      ← Item registration & tablet access controller (OpenTablet, exports)
β”‚   └── sv_vehicles.lua   ← Vehicle database operations & VIN generation (AddVehicle export)
└── client/
    β”œβ”€β”€ main.lua          ← Client bridge, animations, dispatch, UI locales, targeting
    β”œβ”€β”€ lspd.lua          ← Police client commands (panic, backup, dispatch keybinds)
    β”œβ”€β”€ ems.lua           ← EMS client hooks (stub β€” add your logic)
    β”œβ”€β”€ doj.lua           ← DOJ client hooks (stub β€” add your logic)
    └── business.lua      ← Business client hooks (stub β€” add your logic)
[!NOTE] Load order matters. editable/server/main.lua is loaded first among all editable files, so the Bridge and EditTable tables are available when lspd.lua, ems.lua etc. are loaded.

πŸ”§ Server β€” Core Module (editable/server/main.lua)

This is the main bridge between XR-MDT and your framework. It contains:
  • Framework detection and object initialization (QBCore, ESX).
  • The Bridge abstraction layer for all framework operations.
  • EditTable.Events β€” the primary integration points called by the core.
  • EditTable.Functions β€” utility helpers.
  • Event listeners for dispatch and notifications.

Bridge Functions

The Bridge table provides a framework-agnostic API. These functions are used internally by EditTable and by editable/server/lspd.lua, ems.lua, etc.

Player & Job

FunctionSignatureDescription
Bridge.GetPlayer(source) β†’ playerReturns the raw framework player object.
Bridge.GetJob(source) β†’ jobReturns the player’s current job table (normalized for ESX).
Bridge.GetCitizenId(player) β†’ stringReturns the player’s unique identifier (citizenid / identifier).
Bridge.GetCitizenIdFromObject(player) β†’ stringSame, but from the player object directly.
Bridge.GetCharInfo(player) β†’ tableReturns { firstname, lastname, phone }.
Bridge.GetCitizenName(citizenId) β†’ stringDB lookup β€” returns "Firstname Lastname" for a citizenId.
Bridge.GetSource(player) β†’ numberReturns the server source ID from the player object.
Bridge.GetMetaData(player, key) β†’ anyGets a metadata value from the player.
Bridge.SetMetaData(player, key, value)Sets a metadata value on the player.
Bridge.IsOnDuty(player) β†’ booleanReturns true if the player is on duty.
Bridge.GetPlayerByCitizenId(citizenId) β†’ player?Finds an online player by their citizenId. Returns nil if offline.
Bridge.GetPlayers() β†’ tableReturns all online player objects.
Bridge.GetJobFromObject(player) β†’ jobReturns the job table directly from the player object.

Money

FunctionSignatureDescription
Bridge.GetMoney(source, type) β†’ numberGets the player’s account balance. type: 'cash' or 'bank'.
Bridge.AddMoney(source, type, amount) β†’ booleanAdds money to the player’s account.
Bridge.RemoveMoney(source, type, amount) β†’ booleanRemoves money from the player’s account. Returns false if insufficient.
Bridge.DeductMoneyByCitizenId(citizenId, type, amount, reason) β†’ booleanDeducts money by citizenId (handles both online and offline players).

Banking (Society)

FunctionSignatureDescription
Bridge.Bank.GetBalance(accountName) β†’ numberGets a society/business account balance.
Bridge.Bank.AddMoney(accountName, amount, reason?) β†’ booleanDeposits into a society account. Also records in bank_statements.
Bridge.Bank.RemoveMoney(accountName, amount, reason?) β†’ booleanWithdraws from a society account. Also records in bank_statements.

Items & Inventory

FunctionSignatureDescription
Bridge.GetItem(source, item) β†’ table?Returns item data from the player’s inventory.
Bridge.GetItemCount(source, item) β†’ numberReturns the quantity of an item the player has.
Bridge.AddItem(source, item, count, slot?, metadata?) β†’ booleanAdds an item to the player’s inventory.
Bridge.RemoveItem(source, item, count, slot?) β†’ booleanRemoves an item from the player’s inventory.
Bridge.RegisterUsableItem(name, handler)Registers a usable item. Uses ox_inventory:registerHook when available.

Job Management

FunctionSignatureDescription
Bridge.SetJob(player, job, grade)Changes the player’s job.
Bridge.SetJobDuty(player, state)Sets the player’s duty state (on/off).
Bridge.Save(player)Forces a player data save (QB).
Bridge.JailPlayer(source, time)Sends a player to jail via the detected jail resource.
Bridge.UpdateVehicleOwner(plate, targetCitizenId) β†’ numberTransfers vehicle ownership in the DB.

UI & Interaction

FunctionSignatureDescription
Bridge.Notify(source, text, type, length)Sends a notification to a player.
Bridge.RegisterCommand(name, help, arguments, restricted, handler)Registers a command (QB uses QBCore.Commands.Add, ESX uses ESX.RegisterCommand).
Bridge.CreateCallback(name, handler)Registers a server callback (QB uses lib.callback.register, ESX uses ESX.RegisterServerCallback).
Bridge.OnPlayerLoaded(handler)Registers a handler for player load events.

EditTable.Events

These are the primary integration points. The MDT core calls these functions whenever it needs to perform an action that depends on your server’s specific setup.

EditTable.Events.RemoveMoney

Called when the MDT needs to deduct money from a player (fines, taxes, purchases).
ParameterTypeDescription
sourcenumberServer ID of the player.
typestringAccount type: 'cash' or 'bank'.
amountnumberAmount to deduct.
Returns: boolean β€” true if successful.
EditTable.Events.RemoveMoney = function(source, type, amount)
    return Bridge.RemoveMoney(source, type, amount)
end

EditTable.Events.HasItem

Called to check if a player possesses a specific item.
ParameterTypeDescription
sourcenumberServer ID of the player.
itemstringItem name (e.g. 'id_card').
countnumber?Minimum quantity required (defaults to 1).
Returns: boolean
EditTable.Events.HasItem = function(source, item, count)
    local owned = Bridge.GetItemCount(source, item)
    return owned >= (count or 1)
end

EditTable.Events.Query

Every database query in the MDT passes through this function. Override it to use a different SQL library or add query logging.
ParameterTypeDescription
querystringRaw SQL query string.
paramstableParameterized values.
Returns: table β€” Query result rows, or {} on error.
EditTable.Events.Query = function(query, params)
    local status, result = pcall(function()
        return MySQL.query.await(query, params)
    end)
    if not status then
        EditTable.Functions.ReportError(EditTable.Functions.ErrorCodes.DATABASE_ERROR,
            string.format("Query Failed: %s\nError: %s", query, result))
        return {}
    end
    return result
end
[!WARNING] If you aren’t using oxmysql, you must override this function. The entire MDT depends on it for all database operations.

EditTable.Events.SendDispatch

Controls how dispatch alerts are routed to players.
ParameterTypeDescription
data.codestring10-code (e.g. '10-31').
data.titlestringAlert headline.
data.descriptionstringDetailed description.
data.locationstringStreet / area name.
data.jobstableArray of job names to target.
data.coordstable?{x, y, z} coordinates.
data.soundstring?Sound effect name.
data.bliptable?Blip configuration {sprite, scale, color, name}.
EditTable.Events.SendDispatch = function(data)
    local jobs = data.jobs or { 'police' }
    local players = GetPlayers()

    for _, src in pairs(players) do
        src = tonumber(src)
        local playerJob = Bridge.GetJob(src)

        if playerJob and playerJob.onduty then
            local jobName = playerJob.name
            for _, targetJob in pairs(jobs) do
                if jobName == targetJob then
                    TriggerClientEvent('xr-mdt:client:newDispatch', src, data)
                    break
                end
            end
        end
    end
end
[!TIP] Add your webhook logic or external CAD forwarding inside this function after the player loop.

EditTable.Functions (Server)

FunctionSignatureDescription
GetPlayer(source) β†’ playerReturns the framework player object.
GetJob(source) β†’ jobReturns the player’s current job table.
IsOnDuty(source) β†’ booleanChecks if the player is on duty.
GetCitizenId(source) β†’ stringReturns the player’s unique identifier.
ReportError(code, message)Logs a formatted error to console and optionally to Discord.
SendDebug(category, title, message, debugType, fields?)Sends a debug log to console and Discord webhook (only when Config.Debug = true).

EditTable.Functions.ErrorCodes (Server)

CodeConstantMeaning
#ERR-00001DATABASE_ERRORSQL query failed.
#ERR-00002PLAYER_NOT_FOUNDPlayer object could not be resolved.
#ERR-00003INSUFFICIENT_FUNDSNot enough money for the operation.
#ERR-00004INVALID_JOBJob name doesn’t match any configured job.
#ERR-00005ITEM_NOT_FOUNDInventory item not found.
#ERR-00006PERMISSION_DENIEDGrade/rank insufficient for the action.
#ERR-99999UNKNOWN_ERRORFallback for uncategorized errors.

πŸš” Server β€” LSPD Module (editable/server/lspd.lua)

All police-specific logic: player actions, database queries, and generator functions.

EditTable.LSPD.Functions

GenerateSSN()

Generates a unique Social Security Number for citizens (6-digit numeric by default).
EditTable.LSPD.Functions.GenerateSSN = function()
    return tostring(math.random(100000, 999999))
end

GenerateVIN()

Generates a unique Vehicle Identification Number (12-character alphanumeric).
EditTable.LSPD.Functions.GenerateVIN = function()
    local charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    local str = ""
    for i = 1, 12 do
        local rand = math.random(#charset)
        str = str .. string.sub(charset, rand, rand)
    end
    return str
end

GenerateWeaponSerial()

Generates a weapon serial number using Config.WeaponSerialization settings.
EditTable.LSPD.Functions.GenerateWeaponSerial = function()
    local config = Config.WeaponSerialization
    if not config or not config.Enabled then return "UNKNOWN-" .. os.time() end
    -- Builds: "{Prefix}-{Format}" e.g. "SN-A1B2-C3D4"
end

HandleSentence()

Called when a full sentence (fine + jail) is applied. Handles both online and offline players.
EditTable.LSPD.Functions.HandleSentence = function(source, citizenId, fine, jailTime, reason, authorName)
    -- 1. Deduct fine from bank (online or offline DB update)
    -- 2. Add fine to police society account
    -- 3. Send to jail (online) or write to jail_sentences (offline)
    return true
end

-- Backward-compatible alias
function LSPD_HandleSentence(...)
    return EditTable.LSPD.Functions.HandleSentence(...)
end

EditTable.LSPD.Events

FunctionParametersDescription
JailPlayer(source, targetSource, citizenId, time)Sends a player to jail. Handles online and offline scenarios.
FinePlayer(source, targetSource, citizenId, amount, reason)Deducts a fine from the player’s bank and deposits into the police society.
GrantLicense(source, targetSource, citizenId, type)Grants a license via MDT DB and framework metadata.
RevokeLicense(source, targetSource, citizenId, type)Removes a license from MDT DB and framework metadata.
TransferVehicle(source, plate, targetCitizenId)Transfers vehicle ownership in the database.

EditTable.LSPD.Queries

FunctionParametersReturnsDescription
SearchCitizen(query)table[]Searches players by name or citizen ID. Returns processed list with wanted flag.
GetCitizenDetails(citizenId)table|nilFetches full charinfo, job, metadata for a citizen.
SearchVehicle(query)table[]Searches vehicles by plate or model name.
GetVehicleDetails(plate)table|nilReturns full vehicle record for a plate.
UpdateOfficerStats(citizenId, type, amount)voidIncrements an officer’s statistic counter via UpdateStatistic export.
GetWarrants(citizenId?)table[]Returns active warrants (all, or filtered by citizen). Includes firstName/lastName from JOIN.
IssueWarrant(citizenId, reason, author)numberInserts a new warrant into lspd_warrants and returns the ID.
DeleteWarrant(id)voidRemoves a warrant by ID from lspd_warrants.
IsCitizenWanted(citizenId)booleanReturns true if the citizen has any active warrants.
[!NOTE] All queries are framework-aware. The default implementation uses different SQL depending on Config.Framework ('qb'/'qbox' uses players, 'esx' uses users). Override the specific query function if your schema differs.

πŸš‘ Server β€” EMS Module (editable/server/ems.lua)

Medical-specific events and queries for the ambulance/EMS interface.

EditTable.EMS.Events

FunctionParametersDescription
BillPatient(source, targetSource, citizenId, amount, reason)Bills a patient. Online: deducts from bank, adds to ambulance society. Offline: creates phone invoice.
RevivePlayer(source, targetSource)Triggers a revive on the target player.
[!WARNING] EMS_HandleTreatment (used by the ApplyTreatment export) currently contains hardcoded QB-Core calls (QBCore.Functions.GetPlayerByCitizenId, qb-banking). If you use ESX or a different banking resource, override this function in editable/server/ems.lua:
function EMS_HandleTreatment(source, citizenId, amount, treatmentName)
    local targetPlayer = Bridge.GetPlayerByCitizenId(citizenId)
    if targetPlayer then
        Bridge.RemoveMoney(Bridge.GetSource(targetPlayer), 'bank', amount)
        Bridge.Bank.AddMoney('ambulance', amount)
    end
end

EditTable.EMS.Queries

FunctionParametersReturnsDescription
SearchPatient(query)table[]Searches patients by name, SSN, or citizen ID.
GetPatientDetails(citizenId)table|nilReturns charinfo for a specific patient.
UpdateOfficerStats(citizenId, type, amount)voidIncrements an EMS worker’s statistic counter.

βš–οΈ Server β€” DOJ Module (editable/server/doj.lua)

Court system logic β€” case management, citizen/vehicle lookups, and incident management.

EditTable.DOJ.Queries

Case Management

FunctionParametersReturnsDescription
GetPendingCasesCount()numberReturns the total count of incidents in the database.
GetCases()table[]Fetches all incidents with suspects, vehicles, officers, and notes.
SearchCases(query)table[]Searches incidents by title or ID.
CreateCase(data, author)numberCreates a new incident with suspects, vehicles, and officers. Returns the ID.
UpdateCaseStatus(id, status)booleanUpdates the status of an incident (e.g. 'OPEN', 'CLOSED').
UpdateCaseDescription(id, description)booleanUpdates the description text of an incident.
AddIncidentItem(incidentId, type, item)booleanAdds a suspect, vehicle, or officer to an incident.
RemoveIncidentItem(incidentId, type, itemId)booleanRemoves a suspect, vehicle, or officer from an incident.
AddCaseNote(incidentId, note)booleanAppends a note to the incident’s notes JSON.

Citizen & Vehicle Lookups

FunctionParametersReturnsDescription
SearchCitizen(query)table[]Enhanced citizen search with mugshot and wanted status.
SearchVehicle(query)table[]Vehicle search with wanted/stolen tags from lspd_vehicle_tags.
GetVehicleDetails(plate)table|nilFull vehicle details including notes and image.
AddVehicleNote(plate, note, author)booleanAppends a note to the vehicle’s tag record.
DeleteVehicleNote(plate, noteId)booleanDeletes a specific note from a vehicle.
SetVehicleWanted(plate, wanted)booleanFlags or unflags a vehicle as wanted.

Citizen Actions

FunctionParametersReturnsDescription
AddCitizenNote(citizenid, title, content, author)numberAdds a note to a citizen’s record.
SetCitizenWanted(citizenid, reason, author)numberIssues a warrant for the citizen.
AddSentence(citizenid, fine, jail, offense, author)numberRecords a conviction in lspd_convictions.
GrantLicense(citizenid, type, author)numberGrants a license via the DOJ path.

Employee Management

FunctionParametersReturnsDescription
GetEmployees()table[]Fetches all DOJ employees with duty status, callsign, avatar, and activity info.

🏒 Server β€” Business Module (editable/server/business.lua)

Business panel logic β€” employee management, banking queries, and HR operations.

EditTable.Business.Events

FunctionParametersDescription
HireEmployee(source, businessName, targetSource)Hook called when someone is hired (stub β€” add your logic).
FireEmployee(source, businessName, citizenId)Hook called when someone is fired (stub β€” add your logic).

EditTable.Business.Queries

Employee Operations

FunctionParametersReturnsDescription
GetEmployees(jobName)table[]Fetches all employees for a given job from the database.
HireEmployee(citizenId, jobName, grade)booleanSets a citizen’s job in the database (primarily for offline hiring).
FireEmployee(citizenId)booleanSets a citizen’s job to 'unemployed'.
GetPlayerJob(citizenId)table|nilReturns the offline job data for validation.
PromoteEmployee(citizenId, jobName, newGrade)booleanUpdates the grade level of an employee.
UpdateBadge(citizenId, newBadge)booleanChanges the callsign/badge stored in player metadata.
SuspendEmployee(citizenId)booleanToggles the is_suspended metadata flag. Also sets job.onduty = false when suspended.
AddNote(citizenId, newNote)booleanPrepends a note to the employee’s business_notes metadata.
DeleteNote(citizenId, noteId)booleanRemoves a note by ID from business_notes.
GetBusinessBalance(jobName)numberGets the business bank balance via Bridge.Bank.GetBalance() or direct DB query (ESX).

Finance & Banking

FunctionParametersReturnsDescription
GetRevenue(jobName, days, offsetDays?)numberTotal deposit sum from bank_statements for the period. offsetDays shifts the window back.
GetExpenses(jobName, days)numberTotal withdrawal sum from bank_statements for the period.
GetWeeklyRevenue(jobName)table[]Daily revenue breakdown for the last 7 days (for charts). Fields: date_day, total, day_name.
GetRecentTransactions(jobName, limit?)table[]Last N transactions from bank_statements. Default limit: 5.
[!NOTE] Finance queries depend on the bank_statements table. If your banking resource uses a different table or schema, override these functions in editable/server/business.lua.
[!WARNING] Business_HandleBonus (used by the GiveBonus export) currently contains hardcoded QB-Core calls. If you use ESX or a different framework, override this function:
function Business_HandleBonus(employeeCitizenId, amount, businessName)
    local targetPlayer = Bridge.GetPlayerByCitizenId(employeeCitizenId)
    if targetPlayer then
        Bridge.AddMoney(Bridge.GetSource(targetPlayer), 'bank', amount)
        Bridge.Notify(Bridge.GetSource(targetPlayer),
            string.format(Locales.business.bonus_received_notif, amount, businessName), 'success')
    else
        -- Offline: update bank column directly
        if Config.Framework == 'qb' or Config.Framework == 'qbox' then
            local player = MySQL.single.await('SELECT money FROM players WHERE citizenid = ?', { employeeCitizenId })
            if player then
                local money = json.decode(player.money)
                money.bank = (money.bank or 0) + amount
                MySQL.update('UPDATE players SET money = ? WHERE citizenid = ?', { json.encode(money), employeeCitizenId })
            end
        end
    end
end

🌐 Client β€” Core Module (editable/client/main.lua)

The client-side bridge controls animations, UI initialization, dispatch routing, and targeting zones.

EditTable.ClientEvents

FunctionDescription
OpenTablet()Plays the tablet pull-out animation when the MDT opens.
CloseTablet()Stops the animation when the MDT closes.
EditTable.ClientEvents.OpenTablet = function()
    RequestAnimDict("amb@world_human_seat_wall_tablet@female@base")
    while not HasAnimDictLoaded("amb@world_human_seat_wall_tablet@female@base") do Wait(10) end
    TaskPlayAnim(PlayerPedId(), "amb@world_human_seat_wall_tablet@female@base", "base", 8.0, -8.0, -1, 50, 0, false, false, false)
end

EditTable.ClientEvents.CloseTablet = function()
    StopAnimTask(PlayerPedId(), "amb@world_human_seat_wall_tablet@female@base", "base", 1.0)
end
[!TIP] Want a different animation? Change the anim dict and clip name. Want no animation at all? Leave the function body empty.

EditTable.Functions (Client)

FunctionSignatureDescription
GetPlayerData() β†’ tableReturns the current player’s data via the framework bridge.
GetJob() β†’ table|nilReturns the current player’s job table.
IsOnDuty() β†’ booleanChecks if the current player is on duty.
ReportError(code, message)Logs a client-side error with file/line info to console.
Client Error Codes:
CodeConstantMeaning
#ERR-10001UI_ERRORNUI/UI rendering issue.
#ERR-10002CALLBACK_TIMEOUTServer callback exceeded 10-second timeout.
#ERR-10003ANIMATION_ERRORAnimation dict failed to load.
#ERR-10004INVALID_PLAYER_DATAPlayer data is missing or malformed.
#ERR-99999UNKNOWN_ERRORFallback for uncategorized errors.

Bridge Functions (Client)

FunctionSignatureDescription
Bridge.GetPlayerData() β†’ tableReturns the current player’s full data (job, metadata, items).
Bridge.Notify(text, type?, length?)Shows a notification (defaults: type='info', length=5000ms).
Bridge.TriggerCallback(name, cb, ...)Triggers a server callback with a 10-second timeout guard.
Bridge.IsPlayerLoaded() β†’ booleanReturns true if the player is fully loaded (login check).
Bridge.GetClosestVehicle(coords) β†’ entityReturns the closest vehicle entity.
Bridge.GetClosestPlayer() β†’ id, distanceReturns the closest player’s ID and distance.
Bridge.OpenMenu(data)Opens a context menu (uses ox_lib context or qb-menu).
Bridge.AddBoxZone(data)Creates an interaction zone (auto-detects ox_target, qbx_target, qb-target).
Bridge.AddGlobalPlayer(options)Adds global player targeting options.
Bridge.RemoveZone(name)Removes a targeting zone by name.

πŸš” Client β€” LSPD Module (editable/client/lspd.lua)

Police-specific client commands and keybinds.

Registered Commands

CommandKeybindDescription
/bk1β€”Sends a Code 2 backup alert.
/bk2 or /bkβ€”Sends a Code 3 backup alert.
/bk3β€”Sends a Code 3 critical backup alert.
/10-13β€”Triggers an β€œOfficer Down” alert to all emergency services.
/mdt_dispatchβ€”Toggles the dispatch overlay panel.
/panic_buttonCTRL + LSends a panic button alert (10-second cooldown).

πŸ“š Quick Start: Customizing EditTable

Example 1 β€” Custom fine system with Discord logging

-- In editable/server/lspd.lua, replace FinePlayer:
EditTable.LSPD.Events.FinePlayer = function(source, targetSource, citizenId, amount, reason)
    local success = Bridge.RemoveMoney(targetSource, 'bank', amount)

    PerformHttpRequest('YOUR_WEBHOOK_URL', function() end, 'POST',
        json.encode({
            embeds = {{
                title       = 'πŸ’° Fine Issued',
                description = string.format('**%s** was fined $%s\nReason: %s', citizenId, amount, reason),
                color       = 16711680
            }}
        }), {['Content-Type'] = 'application/json'})

    return success
end

Example 2 β€” Custom jail integration

-- In editable/server/lspd.lua, replace JailPlayer:
EditTable.LSPD.Events.JailPlayer = function(source, targetSource, citizenId, time)
    if targetSource and targetSource > 0 then
        exports['my-custom-jail']:SendToJail(targetSource, time)
    end
end

Example 3 β€” Custom database driver

-- In editable/server/main.lua, replace Query:
EditTable.Events.Query = function(query, params)
    return exports['mysql-async']:mysql_fetch_all(query, params)
end

Example 4 β€” Using the Global Logging System

exports['xr-mdt']:AddLog(
    source,
    "police",
    "Armory: Weapon Taken",
    "Took Glock 17 (Serial: #SN-A1B2-C3D4)",
    "Items"
)

Example 5 β€” Custom tablet animation

-- In editable/client/main.lua, replace OpenTablet:
EditTable.ClientEvents.OpenTablet = function()
    -- Use a different animation
    RequestAnimDict("anim@cellphone@pre_selfie")
    while not HasAnimDictLoaded("anim@cellphone@pre_selfie") do Wait(10) end
    TaskPlayAnim(PlayerPedId(), "anim@cellphone@pre_selfie", "enter", 3.0, -3.0, -1, 49, 0, false, false, false)
end

Example 6 β€” Custom Dispatch Handler (Forward to External CAD)

-- In editable/server/main.lua, extend SendDispatch:
EditTable.Events.SendDispatch = function(data)
    local jobs = data.jobs or { 'police' }
    local players = GetPlayers()

    for _, src in pairs(players) do
        src = tonumber(src)
        local playerJob = Bridge.GetJob(src)

        if playerJob and playerJob.onduty then
            for _, targetJob in pairs(jobs) do
                if playerJob.name == targetJob then
                    TriggerClientEvent('xr-mdt:client:newDispatch', src, data)
                    break
                end
            end
        end
    end

    -- Forward to external CAD system
    PerformHttpRequest('https://my-cad-system.com/api/dispatch', function() end, 'POST',
        json.encode(data), {['Content-Type'] = 'application/json', ['Authorization'] = 'Bearer YOUR_TOKEN'})
end

Β© XR-Core Systems | Professional FiveM Resources