Exports
All exports are server side:
exports['kartik-dojjob']:ExportName(...)Staff & permissions
exports['kartik-dojjob']:IsDojStaff(src, ignoreDuty) -- true when the player is DOJ staff (on duty unless ignoreDuty)
exports['kartik-dojjob']:HasPermission(src, 'warrantSign') -- see Permissions for every key
exports['kartik-dojjob']:GetOnDutyStaff() -- staff on dutyBar & lawyers
exports['kartik-dojjob']:GetBarStatus(identifier) -- 'active' | 'pending' | 'denied' | 'suspended' | 'disbarred' | nil
exports['kartik-dojjob']:IsLawyer(src)
exports['kartik-dojjob']:RequestLawyer(src, reason, byPoliceName) -- request id, or false, errSentences & mail
-- 'jail' | 'fine' | 'payout' | 'charge' | 'release'. Offline citizens get it when they next load in.
exports['kartik-dojjob']:Sentence(identifier, 'jail', 20, 'Contempt of court')
-- court mail to the phone, now or when they next load in
exports['kartik-dojjob']:Message(identifier, text, subject)Courtroom & security
exports['kartik-dojjob']:GetSessions() -- running court sessions
exports['kartik-dojjob']:IsLockdown(courtId)
exports['kartik-dojjob']:IsInHoldingCell(src)
exports['kartik-dojjob']:IsRemanded(src) -- waiting for a prisoner transport after sentencingCases
exports['kartik-dojjob']:AddCaseNote(caseId, text, author)
exports['kartik-dojjob']:FileAppeal(caseId, reason, byName) -- new case linked to a decided one
exports['kartik-dojjob']:GetCaseCounsel(caseId) -- active and requested counsel
exports['kartik-dojjob']:GetCaseRole(src, caseId) -- 'court' | 'prosecution' | 'defense' | nil
exports['kartik-dojjob']:ShareRecord(src, caseId, recordRef, note) -- a department member gives an MDT record to a case: exhibit label, or false, err
exports['kartik-dojjob']:CreateDocument(src, templateId, fields, { title = 'Order', caseId = 12 })Orders, supervision & permits
exports['kartik-dojjob']:GetActiveOrders(citizenid) -- restraining / protective / court orders on (or protecting) a citizen
exports['kartik-dojjob']:GetSupervision(identifier) -- active probation / parole / community service
exports['kartik-dojjob']:IsOnProbation(identifier) -- true, row while on probation or parole
exports['kartik-dojjob']:GetPermits(identifier) -- active permits { number, title, slug, expiresAt, details }
exports['kartik-dojjob']:HasPermit(identifier, 'event_permit')Tablet extensions
Add your own panels, pages and actions to the DOJ tablet (for example a licensing or permits script). See Tablet Extensions.
exports['kartik-dojjob']:RegisterExtension(id, definition) -- true, or false, err
exports['kartik-dojjob']:RefreshExtension() -- open tablets reload extension panels
exports['kartik-dojjob']:UnregisterExtension(id)For other MDTs
With Config.CaseStore = 'standalone' the court keeps cases, records and warrants in its own tables. Other MDTs read them here:
exports['kartik-dojjob']:GetCaseStore() -- 'mdt' | 'standalone'
exports['kartik-dojjob']:GetActiveWarrants(citizenid) -- { id, warrant_type, reason, is_dangerous, author_name, created_at }[]
exports['kartik-dojjob']:GetCriminalRecords(citizenid) -- { id, offense, sentence, fine, date, officer_name }[]
exports['kartik-dojjob']:GetCases(citizenid) -- cases where they are defendant or plaintiffVerdict hook (event)
kartik-dojjob:server:onVerdictFinalized fires on the server once for every finished case, so district, economy or stats scripts can react to court outcomes:
- a courtroom verdict from the judge
- a plea agreement accepted by the defendant
It fires right after the verdict is saved. Jail time and a fine in the same ruling count as one event. It never fires again for the same ruling: not after a restart, not when an offline defendant logs in, and not when the sentence is served.
AddEventHandler('kartik-dojjob:server:onVerdictFinalized', function(data)
if GetInvokingResource() ~= 'kartik-dojjob' then return end -- only accept it from the DOJ script
if data.jailDuration > 0 or data.fineAmount > 0 then
-- the case ended with a sentence
end
end)Use AddEventHandler, not RegisterNetEvent, so players can never trigger it.
| Field | Type | Notes |
|---|---|---|
caseId | number | Case id |
resolutionId | string | Unique per resolution, safe to store for your own duplicate checks |
kind | string | 'verdict' or 'plea' |
status | string | 'guilty', 'not_guilty', 'liable', 'dismissed' or 'plea_accepted' |
jailDuration | number | 0 when there is no jail time |
jailUnit | string | 'minutes' |
fineAmount | number | 0 when there is no fine |
judgeCitizenId | string / nil | Judge who gave the verdict |
judgeSource | number / nil | Judge's server id when online |
judgeName | string / nil | Judge on the case |
prosecutorCitizenId | string / nil | Prosecutor who offered the plea (plea only) |
defendantCitizenId | string / nil | Defendant |
resolvedAt | number | Unix time |
To call your own script directly instead, fill in Hook.Custom in bridge/integrations/server/verdict_hook.lua (open file). Hook.Enabled = false in the same file turns the hook off.
function Hook.Custom(data)
exports.my_district_script:CaseResolved(data)
end