CODE3RESPONSE
Exports and events
Everything another resource may rely on. The MDT and voice dispatch use only what's listed here, so it's safe to build on.
Records
Events and exports pass these tables. They're the public record: what a plate or name check shows.
Person
{
id = 12, first = 'John', last = 'Smith', dob = '01/02/1990', gender = 'Male', address = '12 Grove St',
dl = 'Valid', -- 'Valid' | 'Suspended' | 'Revoked' | 'Expired' | 'None'
dl_valid = true,
flags = { 'ARMED AND DANGEROUS' },
warrant = 'Failure to appear', -- or nil
}
A name a driver made up comes as { first, last, dob, gender, unverified = true } with no id: nobody by that name is on file.
Vehicle
{
id = 7, plate = '4ABC123', make = 'Bravado', model = 'Buffalo S', color = 'Black', year = '2015',
owner = 'John Smith', owner_id = 12, reg_valid = true, ins_valid = false,
stolen = false, bolo = true, bolo_reason = 'Armed robbery suspect',
}
model is the display name ("Buffalo S"), not the spawn name.
Callout
{ id = 'domestic_01', name = 'Domestic disturbance', street = 'Grove Street', coords = vector3(...),
priority = 2, description = 'Neighbours report shouting.' }
Truth
Only c3r knows it, and it only comes out through the server export getPedSubject.
{
secret = 'drunk', -- 'clean' | 'nervous' | 'unlicensed' | 'suspended' | 'expired' | 'drunk' | 'drugs' | 'warrant' | 'stolen'
demeanor = 'polite', -- 'polite' | 'nervous' | 'rude' | 'chatty'
id = 'hands', -- asked for a licence: 'hands' it over, 'forgot' it, or gives an 'alias'
alias = nil, -- { first, last, dob }: the false name (id = 'alias')
bac = 0.12, -- secret = 'drunk' only
}
Server events
Fired with TriggerEvent on the server. Listen with AddEventHandler. The first argument is always the officer's server id. These are never net events, so a client can't fake them.
| Event | Arguments | When |
|---|---|---|
c3r:duty | src, on | An officer goes on or off duty |
c3r:contact | src, person | They identify someone (licence handed over, or a name given) |
c3r:vehicleContact | src, vehicle | A vehicle comes into a stop or a check |
c3r:stopStarted | src, person, vehicle | A traffic stop starts. person is nil: the driver isn't known until they're identified, then c3r:contact fires |
c3r:stopEnded | src, outcome | 'cited', 'warning', 'released', 'arrested', 'fled' or 'cancelled' |
c3r:dialogue | src, who, text | Every line of a conversation. who is 'Officer' or 'Subject' |
c3r:note | src, text | A line for the open incident's timeline, e.g. "Breathalyzer, Driver: 0.120 BAC (over the limit)" |
c3r:pursuitStarted | src, person, vehicle | A driver runs instead of pulling over |
c3r:pursuitEnded | src | Caught or lost (before c3r:stopEnded) |
c3r:calloutOffered | src, callout | A call offered to this officer |
c3r:calloutAccepted | src, callout | They responded |
c3r:calloutArrived | src | On scene |
c3r:calloutEnded | src, completed | The call ended for them |
AddEventHandler('c3r:stopEnded', function(src, outcome)
print(('%s ended a stop: %s'):format(GetPlayerName(src), outcome))
end)
Server exports
The SQL-backed exports answer through a callback, because a call from another resource can't wait on SQL inside c3r.
| Export | Returns | Does |
|---|---|---|
isOnDuty(src) | boolean | |
setDuty(src, on) | ok, reason | Puts them on or off duty |
getPerson(id, cb) | cb(person | nil) | |
getVehicle(id, cb) | cb(vehicle | nil) | |
findVehicle(plate, cb) | cb(vehicle | nil) | A plate on file |
lookupPlate(src, plate, cb) | cb(vehicle | nil) | Like findVehicle, but a plate not on file is looked for near that officer: if the car is there, it gets papers, an owner and a driver on the spot, and c3r:vehicleContact fires |
createPerson(p, cb) | cb(person) | An existing name + date of birth comes back unchanged |
createVehicle(v, cb) | cb(vehicle) | |
getPedSubject(netId) | person, vehicle | nil, items, truth | Everything c3r knows about a ped it made; nil if it didn't make it. Returns directly |
endStop(src, netId, outcome) | boolean | Ends that officer's stop on that ped. true when it did |
setCalloutOffers(src, on) | Callout offers on or off for that officer | |
offerCallout(src) | ok, reason | Offer them a call now |
exports.c3r:lookupPlate(src, '4ABC123', function(vehicle)
if vehicle and vehicle.stolen then print('Stolen!') end
end)
Client exports
| Export | Returns | Does |
|---|---|---|
isOnDuty() | boolean | Reads the c3rDuty state bag |
getService() | 'police' | nil | The service they're on duty in |
setDuty(on) | true | Absolute, never a toggle |
isOnCallout() | boolean | |
isOfferedCallout() | boolean | |
acceptCallout() | ok, reason | |
completeCallout() | ok, reason | |
requestService(kind) | ok, reason | Sends an AI unit (kinds below) |
cancelService(kind) | ok, reason | |
requestPursuitBackup(level) | ok, reason | 'light', 'medium', 'heavy' or 'air'. With no chase on, light to heavy sends a cover unit |
cancelPursuitBackup() | ok, reason | Cover units leave too |
towTarget() | vehicle | nil | The car a tow would be sent for now: the stop's car, else the nearest empty one within 15 m |
pa(cmds) | boolean | Gives PA orders: a command or a list, in the order said. true when an order went out |
getStop() | table | nil | The officer's traffic stop: { veh_net, ped_net, stopped, mode, people = { { net, seat, role, out } } }. mode is 'front', 'behind', 'steer' or nil |
Service kinds: ambulance, police (prisoner transport), tow, coroner, fire, mechanic, roadservice, animalrescue, taxi, cover.
PA commands: pull_over, felony, driver_out, passenger_out, everyone_out, walk_back, kneel, hands_up, back_in, engine_off. On a felony stop only the first runs.
Reasons (the second value when the first is false): off_duty, not_available (unknown kind or its models missing), already_en_route, no_route, no_prisoner, no_vehicle, nobody_to_collect, too_far, no_pursuit, enough_units, not_en_route, already_dispatched, no_backup.
local ok, why = exports.c3r:requestService('ambulance')
if not ok then print('No ambulance: ' .. why) end
State bags
| Bag | On | Value |
|---|---|---|
c3rDuty | Player | true while on duty (set by the server, replicated) |
if LocalPlayer.state.c3rDuty then --[[ on duty ]] end
Stuck? Ask on Discord
View as Markdown