Skip to content

Exports & events ​

All exports are server-side. Nothing here can be called or triggered from a client, so a client can't sneak calls onto the dispatch board.

Identity ​

server Always available.

ExportReturnsDescription
GetDiscordId(src)"123…" | nilThe player's Discord id
GetEmployee(src, cb)via cb(employee, reason)Looks the player up in the MDT (scope employees:read). Cached for a minute
GetEmployeeCached(src)employee | nilCached value only, no network. For display purposes
lua
exports.np_mdt:GetEmployee(source, function(employee, reason)
  -- employee = { name, badge, badgeNumber, onDuty, duty, suspended,
  --              ranks = { { label, inGameKey, source } }, ranksComplete }
  -- reason   = "no-discord" | "not-employee" | "unavailable"
end)

ranksComplete is false when Discord couldn't be reached and some ranks come from Discord roles. Don't take rights away based on an incomplete list.

Dispatch ​

server Needs Config.Modules.dispatch. Otherwise they return false, "Modul dispatch ist aus …".

ExportReturnsDescription
ReportCall(call)ok, errReport or update a call. The same externalId updates it
ResolveCall(externalId, resolution?)ok, errClose a call that was settled in game
lua
exports.np_mdt:ReportCall({
  externalId = "robbery:fleeca-legion",   -- same id = update
  kind = "alarm",                          -- notruf | panik | alarm | hinweis
  priority = 1,                            -- 1 high, 2 normal, 3 low
  title = "Stiller Alarm Fleeca Bank",
  message = "Tresorraum",
  location = { x = 149.9, y = -1040.5, street = "Vespucci Blvd" },
  caller = { name = "Fleeca Bank", phone = "555-0100" },
})

exports.np_mdt:ResolveCall("robbery:fleeca-legion", "cleared")

externalId and title are required. externalId may contain A-Z a-z 0-9 . _ : -, at most 80 characters. Field limits are on the API page.

The same works with events from a server script (registered with AddEventHandler, not as net events):

lua
TriggerEvent("np_mdt:dispatch:report", call)
TriggerEvent("np_mdt:dispatch:resolve", externalId, resolution)

Medic: emergency calls ​

server Needs Config.Modules.medic. A dispatch view or dispatch script reads emergency calls only through these exports and events, never from internal tables.

ExportReturnsDescription
getActiveMedicCalls()Call[]Open calls, never a resolved one
getMedicCall(id)Call | nil
claimMedicCall(id, badge, name)ok, errerr e.g. "already_claimed"
resolveMedicCall(id, reason)ok, errreason: reached, died, respawned, disconnected

They're called …MedicCall on purpose, so they don't get mixed up with ResolveCall from the dispatch module.

Medic: integration ​

server Needs Config.Modules.medic. Exports that need a patient answer no_patient_store while the simulation is off, and no_patient for a player without an entry.

ExportDescription
registerSubstance(key, def)Register a substance (drug, alcohol …). A second call with the same key replaces it
administer(serverId, key, doseMg, route)Give a registered substance. route: iv, io, im, oral, inhaled, topical
getPatientSummary(serverId)Read only, safe to poll
applyInjury(serverId, spec)Escape hatch
setStateVariable(serverId, name, value)Escape hatch
setRhythm(serverId, kind, rate)Escape hatch
knockOut(serverId, reason)Escape hatch
lua
exports.np_mdt:registerSubstance('ethanol', {
  label = 'Ethanol', class = 'alcohol', onsetS = 300,
  tAbsorbHalfS = 600, tElimHalfS = 5400, distributionVolume = 40000,
  effect = function(state, level) return { consciousness = -0.3 * level } end,
})
exports.np_mdt:administer(serverId, 'ethanol', doseMg, 'oral')

label, class, effect, tAbsorbHalfS and tElimHalfS are required. effect must be pure (no natives, no randomness, no clock). It's recomputed every second from all substances, and level is effective mg divided by distributionVolume.

The escape hatch

applyInjury, setStateVariable, setRhythm and knockOut are a supported way to break the simulation. Three scripts that each push consciousness around give you a patient nobody can reason about. Use the substance registry for anything substance-like. The hatch clamps values to documented ranges, marks injected injuries as reported, logs each call with the calling resource, and can be turned off with Config.Medic.Integration.hatchEnabled = false. If a patient behaves impossibly, check that log first.

Events ​

Local events. Listen with AddEventHandler on the side shown.

EventSideArgumentWhen
np_mdt:medic:callCreatedservercallAn emergency call was created
np_mdt:medic:callUpdatedservercallAn emergency call was updated again or claimed
np_mdt:medic:callResolvedservercallAn emergency call was resolved
np_mdt:medic:stageChangedserver{ serverId, from, to, direction }A patient's stage changed in the simulation tick
np_mdt:medic:patientDiedserver{ serverId }A patient died
np_mdt:medic:patientTreatedserver{ serverId, intervention, outcome }A treatment was carried out in game. No medic name
np_mdt:medic:hospital:imageReadyclientfindingsX-ray or CT findings arrived on this client

Commands ​

CommandSideAccessDescription
mdtstatusserverconsole, ACE command.mdtstatusSetup and status overview
medicstatusserverconsole, ACEMedic sync status
medicrevive <id>serverconsole, ACE command.medicreviveRevive a player
medictransport [id]serverconsole, ACETransport state of a player
mdtclienteveryone (tablet module)Open / close the tablet (F10)
status <label>clienteveryone (funk module)Set your unit's status
np_mdt_panicclienteveryone (funk module)Panic button (key "MDT: Panikknopf")
notruf <text>servereveryone, if Config.Dispatch.command.enabledText emergency call
wartenummerservereveryone (kiosk module)Draw a queue ticket at a kiosk

The medic module's player commands are listed on the Medic module page.

np_* FiveM resources