FIELD MANUAL // Police tools

Precinct

Documentation from the supplied script archive. Check your included resource files for the version you install.

Precinct

By QBₓ BØNES · v1.0.0

A complete police job for Qbox, QBCore and ESX. It replaces qbx_police / qb-policejob / esx_policejob.

  • Field: soft and hard cuffs, escort (the suspect walks with you), put in / take out of vehicles, search, seize cash and illegal items, GSR test, revoke licenses, mugshots
  • Seized items become evidence: they go into your inventory tagged "Evidence #12 · seized from ..." (or the evidence locker numbered after the evidence entry), so they can be tested, attached to reports and confirmed at the lab.
  • Traffic stops: in a police car, pull over the vehicle in front.
  • Players get a pull-over signal, and their plate is run for you.
  • Locals (NPCs) pull over to the side and wait for you. You can talk to the driver (ID, license, insurance, warrants, stolen car, alcohol), order them out, write them a citation, or release them. Some floor it instead, which sends a dispatch alert.
  • Parking tickets: leave one on a parked car's windshield. The registered owner is billed now, or when they next log in. Anyone can read the ticket, and the MDT vehicle page lists all tickets for that plate.
  • Booking desk: bring a cuffed suspect to the station desk. You get the mugshot, fingerprints and record check, with warrants and priors, on one booking sheet, then go straight to charges and jail.
  • Citations and arrests: a penal code screen with charges, fines and jail time. Works with xt-prison, qb-prison, rcore_prison, or a built-in jail.
  • Ticket book: citations are written on a paper ticket: name, date of birth, car and location fill in for you, you add violations, speed and notes, sign it and hand it over. The person signs it (or refuses) and keeps a readable citation item.
  • MDT tablet (F6):
  • people and vehicle lookups, profiles with records, warrants, tags and notes
  • reports, warrants, BOLOs and the evidence log
  • Dispatch live map: every call and every on-duty unit on the map, updating live. Click a call to respond (sets your GPS) or send another unit to it (their GPS is set and they're told). Mark a call drops a new call anywhere on the map for every officer. The map is the game's own map, shown live: whatever map your server streams (a postal map pack shows its postal codes), so there's no picture to make (Config.Dispatch.map = 'game'). Postals: with Config.Dispatch.postals = 'auto' the codes come from nearest-postal (the same file it uses), so every call shows its postal (MDT, alert pop-up, blip), and the postal box jumps to a postal and can set your GPS there. The # button draws Precinct's own postal labels on top (for a map without postals printed on it). Have your own map picture instead? Set map = 'image' and put it at html/img/map.jpg with html/img/map.json giving the world area it covers: {"minX":-4200,"maxX":4600,"minY":-4400,"maxY":8400,"w":2640,"h":3840}.
  • the roster with callsigns
  • Guide: a searchable how-to for officers, command and admins, built into the MDT, showing this server's own keybinds. Edit the text in html/js/guide.js.
  • Personnel: duty hours per officer, promotions, demotions, firing, service records, and field training sign-offs for new hires
  • Planning Board: a board per case. Pin people, vehicles, evidence, reports and notes, connect them with string, drag them around, and double-click a card to open it.
  • Station:
  • armory by rank
  • motor pool and helipad
  • locker room: wardrobe and a personal locker
  • evidence lockers per case, impound lot, crime lab
  • DR-2 radar: front and rear antennas with target, fast and patrol speeds on 7-segment displays.
  • Same/opposite direction modes, locks and a fast-limit alarm.
  • Doppler audio and a remote control. The displays can be dragged and resized.
  • ALPR plate reader: reads front and rear plates and flags BOLOs and owners with warrants.
  • Field tests: breathalyzer (BAC from drinks), drug test kit, GSR, fingerprint scanner, and ID check (the person gets asked to hand it over).
  • Narcotics field test kit: test seized drugs with reagent pouches, like real NIK kits.
  • Pick a pouch (Marquis, Scott, Duquenois-Levine, Simon's, Ehrlich, Mandelin), drop the sample in, break the 3 ampoules, shake it, and compare the color to the chart printed on the pouch.
  • The wrong pouch shows no reaction, and cut drugs give a fainter color.
  • The bag gets tagged with the result, the test is logged in the MDT, and the crime lab can confirm the real substance and purity.
  • Ankle monitors: cops see the wearer on the map. Cutting one off sends a dispatch alert.
  • Vehicle tools: tint meter, GPS trackers (anyone can search a car for one) and impound.
  • Scene props: placed with a live see-through preview. Pick from 20+ props, or add your own streamed props. Spike strips actually pop tires.
  • Evidence: bullet casings and blood are left in the world, then bagged and analysed at the lab.
  • Forensics:
  • Crime scene camera (evidence_camera): a real DSLR viewfinder with zoom, flash, grid and focus. Every shot is a real screenshot saved to the MDT and tagged with the place, time, the vehicle plate or marker in frame, and the evidence nearby.
  • Darkroom (MDT → Photos): looks (Forensic, B&W, Noir, Luminol, Night boost), adjustments, crop, arrows, circles, numbered evidence tags, a 10 cm forensic scale, text, redaction and an info stamp. The original is always kept.
  • Case boards: photos are filed under cases and pinned to the case boards as polaroids.
  • UV light (uv_light): evidence glows from further away. Drivers leave latent prints on vehicles, which you lift and send to the lab to get a name.
  • Case files and warrants: build a file on a suspect with:
  • probable cause and charges
  • evidence from the log, photos, statements and reports
  • automatic suggestions for anything already on file that links to them (lab matches, seizures, interviews)

An evidence strength meter scores the file: forensic matches count most, and mixing kinds of evidence adds more. Once it's strong enough, request an arrest warrant or a search warrant (vehicle, property or person). Supervisors (grade 3+) or judges (/judge, job judge) review the whole packet and approve or deny it with a note. Approved arrest warrants become active warrants, and search warrants expire after 24h. Settings are in config/casefiles.lua; by default only reviewers can issue a warrant directly. - Paper case files and warrants: - Print file: on the MDT case file it creates a case_file item holding a frozen copy of the whole file. Using it opens a paper dossier with: - a cover page and probable cause - every exhibit with its own picture, which you can click to examine with full details and chain of custody - statements and warrants - Signing: hand the file to a judge (or a grade 3+ supervisor). They can sign or deny its warrant requests, or write a new arrest or search warrant, straight from the paper. They get a signed warrant_doc item to hand back. - Printing approved warrants: approved warrants can also be printed from the MDT request page. - Scene photos: bagged evidence is photographed in place first, with a numbered evidence tent (and the object itself, for DNA traces). Turn it off with Config.Evidence.scenePhotos = false. - Crime lab: a full lab screen with an evidence queue, the item on the bench in its evidence bag, and a live instrument run that ends in a signed lab report: - casings: comparison microscope - blood: centrifuge and ABO/Rh typing card - DNA: genetic analyzer and database search - prints: AFIS with minutiae - drugs: GC-MS chromatogram and mass spectrum

The Ballistics bench test-fires guns into the water tank. Config.LabScreen = false brings back the simple list. - Detective work: - Ballistics: at the lab, test-fire a gun you carry and it's matched against every casing on file. Guns get a hidden barrel mark the first time they fire, so filed-off serials still match. - Store CCTV: every store records who was inside (outfit, where they stood, if they had a gun out) for 90 minutes. At the store's counter, officers scrub the timeline and grab stills. The still rebuilds that moment from the recording and saves it to Photos. - Witness statements: F7 near a person → Paperwork → Take statement. The witness writes and signs it on their own screen. - Interviews: at the interview recorder (station point), both people type and every line is timestamped. Officers can read the subject their rights. It's saved in MDT → Statements and can be pinned on case boards. - DNA (dna_swab): people leave DNA on what they eat, drink and smoke, and on steering wheels. Swab it and the lab gives a DNA profile. It only names someone whose reference sample is on file: booked suspects get one automatically, or you can take a cheek swab from a cuffed suspect. Old swabs start matching as soon as the person is booked. Other scripts can call exports.precinct:DropDNA(source, 'Cigarette butt'). - Officer kit: bodycam overlay, car PA (pma-voice), an F7 police radial menu, and a radial on every person. - Fully custom UI: menus, radials, dialogs, progress bars, prompts and notifications. Nothing looks like stock ox_lib. - Dispatch: alerts with blips, panic button, automatic shots-fired calls, on-duty unit blips - Unit status: 10-8, 10-6, en route, on scene and 10-7, shown on the roster and the dispatch map. Responding to a call (or being sent to one) puts you en route, and you go on scene automatically when you get there. Set it from the MDT header or /status 10-6. - Helicopter camera (FLIR): a gimbal camera in police helicopters. Zoom, night vision and thermal, a spotlight every player sees, plate reads from the air (with BOLO / warrant flags), locking on a vehicle and marking it as a dispatch call for ground units. - Court and DA: send a case file to the DA. The DA charges it, declines it, offers a plea deal (the defendant accepts or turns it down in game) or sets a hearing. A judge gives the verdict, and the fine and jail are carried out, now or when the defendant next logs in, and the conviction goes on their record. - Departments keep their own investigations: evidence, case files, Planning Boards, photos and statements are only seen by the department that made them. People, records, reports, warrants and BOLOs are state wide. - Evidence lockers in the MDT: everything in your department's station lockers, with destroying an item for senior ranks (logged). - 911 / 311: anyone can call the police with /911 or /311 (or from their phone: calls and texts to 911 / 311 on npwd and lb-phone). The call lands in dispatch with the caller's location; more texts go on the same call, and officers text back from the MDT call panel. The reply arrives as a text (npwd, lb-phone, roadphone) or a notification on any other phone. Other phones plug in through bridge/phone_server.lua. - Citizen portal: /records (or the Citizen app on lb-phone) shows a player their own fines (and lets them pay), court cases, hearing dates, plea deals to accept or turn down, and their record, plus a contact-the-police form. - Command stats: MDT → Personnel → Stats: hours, arrests, citations, tickets, reports, evidence and call response times per officer, and every department side by side over 7, 30 or 90 days.


Install

  1. Remove your old police job: qbx_police / qb-policejob / esx_policejob. Don't run two.
  2. Put precinct in your resources and add ensure precinct to server.cfg after ox_lib, oxmysql, your framework, inventory and target.
  3. Start the server. The database tables are created automatically, so there's no SQL to import.

Needs: ox_lib, oxmysql, ox_target or qb-target.

Some features need a specific script: saved trunks / gloveboxes and the MDT evidence locker list need ox_inventory; door damage and repairs after raids need ox_doorlock; house owners paying for door repairs need qbx_properties or qb-houses; real photos (mugshots, scene camera) need screencapture or screenshot-basic. Everything else works on Qbox, QBCore and ESX.

Works with: - Inventory: ox_inventory, qb-inventory - Jail: xt-prison, qb-prison, rcore_prison - Keys: qbx_vehiclekeys, qb-vehiclekeys, wasabi_carlock - Clothing: illenium-appearance, qb-clothing, esx_skin - Fuel: ox_fuel, LegacyFuel, cdn-fuel, ps-fuel - Mugshots: MugShotBase64

Precinct finds all of these automatically.

Items

Most come with ox_inventory / qb-core already: handcuffs, empty_evidence_bag, filled_evidence_bag, radio, armour (armor on QBCore).

Tool items: every police tool is an item that officers take from the armory (Tools tab):

Item What it does Used up?
breathalyzer Breath test No
drugtest Drug swab One per test
narcotics_kit Narcotics pouches (see below) One pouch per test
fingerprint_scanner Fingerprint ID No
radar_gun Handheld radar No
tint_meter Window tint reading No
spikestrip Spike strip Given back when picked up
gps_tracker Vehicle tracker One per tracker
flashlight Pulls out the police torch (use again to put it away; hold right mouse to raise it) No
ankle_monitor Ankle monitor Given back when removed
zipties Lets anyone tie people up One per use
battering_ram Pulls out a sledgehammer to breach doors No

Use them from the inventory and they work on the closest person or vehicle, or use the target / F7 menu as before (you still need the item on you). To go back to no items, set the item to false in config/tools.lua (Config.Tools, Config.NarcoKit, Config.AnkleMonitor, Config.Tracker) or config/main.lua (Config.Spikes, Config.Evidence.emptyBagItem).

For ox_inventory, add them to data/items.lua. consume = 0 stops ox_inventory using them up itself (Precinct does that):

['breathalyzer']        = { label = 'Breathalyzer',        weight = 300, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/breathalyzer.png' } },
['drugtest']            = { label = 'Drug Swab Kit',       weight = 50,  stack = true,  close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/drugtest.png' } },
['narcotics_kit']       = { label = 'Narcotics Test Kit',  weight = 400, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/narcotics_kit.png' } },
['fingerprint_scanner'] = { label = 'Fingerprint Scanner', weight = 400, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/fingerprint_scanner.png' } },
['radar_gun']           = { label = 'Radar Gun',           weight = 900, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/radar_gun.png' } },
['tint_meter']          = { label = 'Tint Meter',          weight = 300, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/tint_meter.png' } },
['spikestrip']          = { label = 'Spike Strip',         weight = 4000, stack = true, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/spikestrip.png' } },
['gps_tracker']         = { label = 'GPS Tracker',         weight = 150, stack = true,  close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/gps_tracker.png' } },
['ankle_monitor']       = { label = 'Ankle Monitor',       weight = 500, stack = true,  close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/ankle_monitor.png' } },
['zipties']             = { label = 'Zip Ties',            weight = 20,  stack = true, client = { image = 'nui://precinct/html/img/items/zipties.png' } },
['evidence_camera']     = { label = 'Crime Scene Camera',  weight = 900, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/evidence_camera.png' } },
['case_file']           = { label = 'Case File',           weight = 150, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/case_file.png' } },
['warrant_doc']         = { label = 'Warrant',             weight = 20,  stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/warrant_doc.png' } },
['citation']            = { label = 'Citation',            weight = 10,  stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/citation.png' } },
['dna_swab']            = { label = 'DNA Swab Kit',        weight = 30,  stack = true,  consume = 0, client = { image = 'nui://precinct/html/img/items/dna_swab.png' } },
['uv_light']            = { label = 'UV Forensic Light',   weight = 400, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/uv_light.png' } },
['flashlight']          = { label = 'Police Flashlight',   weight = 500, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/flashlight.png' } },
['battering_ram']       = { label = 'Battering Ram',       weight = 4000, stack = false, close = true, consume = 0, client = { export = 'precinct.useItem', image = 'nui://precinct/html/img/items/battering_ram.png' } },

On qb-inventory / ESX the items are made usable automatically. Add them to your items list (qb-core/shared/items.lua) and copy the pictures from precinct/html/img/items/ into your inventory's image folder.

Battering ram: after adding the battering_ram item definition, restart ox_inventory and precinct, then give the item to an officer and use it. The officer carries Precinct's own door ram (precinct_battering_ram, streamed with the resource) down at his side in one hand by its front handle, like a toolbox (Rockstar's own jerrycan carry); press E near a supported door to breach or X to put it away. To breach, the officer steps side-on to the door (door on his left, squared up to the door face) and swings the ram into it. The swing is Precinct's own animation (stream/precinct@ram_carry4.ycd: clips ready and strike); without that file the officer shoves the ram forward instead. /precinctram also toggles it when the inventory item has not been wired up; outside raid test mode, this command still requires the item and police duty. config/raids.lua currently has testMode = true for testing; set it to false before opening the server to players.

Config.Raids.ramProps lists the held models in order; the first one that exists is used, each with its own bone, offset, rot, idleAnim (carrying), breachAnim (the side-on swing; reach / ahead are where the ram face is at impact, so the officer lines up at the right distance), swingAnim and thrust (fallbacks if the breach clips aren't streamed). If the ram model isn't streamed, the base-game sledgehammer is used instead, over the shoulder with a large-tool swing. With fitHands = true the ram's handles follow the officer's palms every frame (and with alignHands it points along the line from the rear hand to the front hand), so it sits in the hands on any ped model and with any idleAnim / swingAnim; its offset then only nudges it from there. To nudge it, put it away and type /precinctprop ram, then paste the copied offset / rot lines into its entry. impactDelayMs and swingDurationMs set the timing of each hit.

Door repairs and tape: after a breach, an officer tapes the door off (G): the door stays open, with police tape across it (an X and a band, on the side it was breached from) and hidden barriers behind the tape so nobody can walk or climb through. It stays like that until it's repaired: the owner repairs it for Config.Raids.repair.cost from their account, or an on-duty officer repairs it and the department account pays (police = 'society', or 'free', or false so only the owner can). A repair closes and locks the door again. Turn the tape off with tape = false.

Raid aftermath: With Config.Raids.aftermath = true, a real breach creates a persistent damaged entry in the precinct_raid_damage table. An ox_doorlock door stays unlocked until an on-duty officer walks to it and presses G to secure it. A qb-houses entrance keeps its ram state until secured. A qbx_properties entry keeps a recorded damage state; its temporary officer key is still removed automatically after entry. A small in-world label shows the damage or secured state. After police secure the entry, its current housing owner can press G to repair it and clear the record. The server checks distance, duty, ownership, and the current state for each action. The related raid file logs securing and repair.

On the final successful hit, an ox_doorlock door unlocks and swings open, then stays held open until police secure it. Players arriving later see the saved open state. Single and double door opening angles are adjustable with breachOpenRatio, breachDoubleRatios, and breachOpenOverrides in config/raids.lua. Some MLO door models have unusual hinges or are not movable by GTA's door system; tune the ratio for those doors in-game. Housing shells use their housing adapter's entry transition rather than a physical swinging door.

The swing direction is chosen from the officer's position at the breach. The automatic sign is reversed based on the reported house MLO swing so its leaves should swing into the property. The breach position is saved with the damage record so later players see the same direction. breachOpenOverrides accepts signed angles for doors with different model pivots.

The door effect moves the mapped ox_doorlock object itself and holds its pose. Each leaf keeps its own object handle and original position and heading, which are restored before it is unfrozen when police secure the entry. If the object cannot be found, the breaching player's F8 console prints its door key; confirm that ox_doorlock's saved model and coordinates match the streamed door. A shell entrance without a mapped ox_doorlock object cannot physically swing open.

The default breach is one guaranteed swing (hits = 1, maxSwings = 1, skill = false). Server warrant, item, and distance checks still apply.

For an ox_doorlock door with no housing owner, give a maintenance role add_ace group.admin precinct.raid.repair allow (or another chosen ACE principal) so someone can clear the secured damage record. The game door model itself is not swapped; the doorlock state and in-world damage label show the aftermath. testMode = true lets anyone try the full sequence; set it to false for normal police and owner restrictions. With aftermath = false, the original relockMinutes and shellOpenMinutes timers apply.

Narcotics test kit: with ox_inventory one kit holds 10 pouches (Config.NarcoKit.uses); other inventories use up one item per test.

Drug items are matched in Config.NarcoKit.substances. Drug scripts can also set item metadata: substance = 'Cocaine' (or false for a fake bag) and purity = 0-100.


Setup

Everything is in config/:

File What's in it
main.lua Police jobs, keybinds, cuffs and escort walk, searching and where seized items go, fines, parking tickets, traffic stops, jail, dispatch, radar, evidence, MDT
tools.lua Breathalyzer and alcohol items, drug test and drug items, ankle monitor, GPS tracker, bodycam, car PA
forensics.lua Crime scene camera, UV light and latent prints, ballistics, store CCTV (store list), statements and interviews, DNA (items that leave traces)
props.lua Scene props by category (any model, including your own streamed props)
stations.lua Stations per department (LSPD, BCSO, SAST): duty, armory, locker, evidence, lab, booking desk, impound, garages, recruitment officer; department applications
personnel.lua Duty hours, who can promote / demote / fire, weekly hours target, field training (FTO) checklist and what trainees can't use yet
armory.lua Armory items by rank
vehicles.lua Garage vehicles by rank and department
penalcode.lua Charges, fines and jail time

Using an MLO? Stand on the spot and type /precinctcoords. The position is copied to your clipboard.

Departments and stations: each department has its own station: LSPD at Mission Row, BCSO at Paleto Bay, SAST at Sandy Shores. A station's jobs can use its armory, locker and garages; the spots in Config.SharedStationPoints (duty, booking, mugshots, interviews, lab, evidence, impound) work for any officer at any station. Add more stations by copying a block in config/stations.lua with a new id.

Moving stations in game: /precinctstations (admins) opens the station editor. Stand where a spot should be and pick Add one here or Move it here; armory and recruitment peds face the way you face, and garage spawns use your heading (sit in a car to line one up). You can also move the map blip and rename a station. Changes save to data/stations.json, win over the config file, and update for every player at once. Back that file up before replacing the resource folder on an update.

Department applications: every station has a recruitment officer (recruiter) anyone can talk to. Players apply to that department with the form in Config.Applications.questions (give a department its own form by adding its job name as a key), and can check their application there. Officers of that department at reviewGrade or above read applications at the same ped and accept or deny them with a note. Accepting hires the applicant into the station's dept at hireGrade; anyone offline gets hired and told the outcome when they next log in. After a denial they can reapply after reapplyHours. On-duty reviewers are pinged about new applications, and a Discord webhook can log them.

Personnel and duty hours (MDT → Personnel): every minute an officer spends on duty is logged, whatever put them on duty. The page lists everyone in your department (online or not) with their rank, last 7 and 30 days of hours, and when they were last on. Open an officer for a 14-day hours chart, their shifts, their training and their service record. Officers at Config.Personnel.manageGrade or above can change ranks, let people go (with a reason), make someone a Field Training Officer, and add notes, commendations and write-ups. They can only act on officers below them and only give ranks below their own (precinct.admin ace skips that). Hires, promotions, demotions, firings and training sign-offs all land on the service record, and a Discord webhook can log them. Changes to offline officers apply straight away on Qbox and ESX; on QBCore they apply when the officer next logs in. Set weeklyHours to flag anyone under a weekly target.

Field training (FTO): an accepted application puts the new hire into field training. Until a Field Training Officer (Config.Training.ftoGrade+, or anyone command marks as FTO) signs off every task on the checklist in their MDT profile, the trainee can't take a vehicle from the motor pool without a trained, on-duty officer next to them (rideAlong), and the armory items in Config.Training.armory stay locked. The last sign-off finishes training (optionally promoting them, promoteTo). Command can also start training for anyone, or sign the whole checklist off at once for an experienced transfer. Change the checklist in Config.Training.tasks, per department if you like. Other scripts: exports.precinct:IsTrainee(source) and exports.precinct:GetDutySeconds(citizenid, days).

Sub-divisions (SWAT, K9, Traffic, Air Support, Detectives): set them up in Config.Divisions (config/personnel.lua): name, callsign prefix, colour, map blip colour, and which departments have it. Command puts officers in or out of a division and picks its leads from the officer's Personnel page (Divisions button); leads can add and remove members of their own division. Add division = 'swat' (or a list) to a vehicle in config/vehicles.lua or an item in config/armory.lua to lock it to that division. On duty, officers choose what they're working as by clicking their callsign on the MDT: the prefix goes in front of their unit name (K9 · 1-ADAM-12 · Hart) and their map blip takes the division colour. Division tags show on the Roster and Personnel pages, and Personnel can filter by division. Other scripts: exports.precinct:GetDivisions(source) and exports.precinct:InDivision(source, 'swat').

Saved police cars and the customization bay: each department takes cars from its own fleet in config/vehicles.lua (LSPD, the Sheriff fleet for BCSO and LSSD, SAST). With Config.Garage.saved, a car an officer takes becomes theirs (up to maxSaved): the garage has a My vehicles tab next to the Fleet tab. Parking it (third eye on the car → Store vehicle) keeps everything in its trunk and glovebox (ox_inventory), and taking it out again puts it all back, along with its look. Cars that are out get their trunk / glovebox backed up every autosave minutes, and when a car is destroyed. Let a car go from My vehicles to free a slot.

To customize, drive your own saved car onto a customization bay and press E: paint (primary, secondary, pearlescent, wheels, interior, dashboard, any custom colour), liveries and livery sheets, roof liveries, extras (light bars, push bars...), every body part the model has, wheel type and rims, custom tires, window tint, xenon headlights and colour, plate style, and performance (engine, brakes, gearbox, suspension, armor, turbo; turn that off with performance = false). Drag to turn the camera, scroll to zoom. Save look keeps it for every time the car comes out; Cancel (or Esc) puts it back how it was. Place bays with /precinctstations → a station → Customization bay; a station without bays uses its garage spawn spots. Car pictures for the garage go in html/img/vehicles/<model>.png. Added your own cars? Type /precinctcarpics (admins) and every garage car without a picture gets photographed in game on a green screen and saved there; /precinctcarpics all redoes them all, /precinctcarpics bearcat x3bearcat only those. Needs screencapture or screenshot-basic. Restart precinct when the console says it's done.

MDT photos: with screencapture or screenshot-basic running, every character gets a real, sharp photo on their MDT profile (Config.MDT.idPhotos): when they make their ped, when they load in without one, after they save a new look (illenium-appearance, qb-clothing, esx_skin, fivem-appearance), and when it's older than idPhotoDays. The camera only cuts to their face for half a second while they stand still on foot, out of any menu. A booking mugshot taken by an officer always wins and is never replaced. MugShotBase64 (GTA's small blurry headshot) is only used when no screenshot resource is installed. Photos are taken against a green screen and put on a backdrop (Config.MDT.photoBackground): a blue ID backdrop for ID photos and a height-chart wall with a booking placard for mugshots. Use blue, grey, white, chart, or your own picture (img/photo/yours.png, put it in html/img/photo/).

Precinct's own props: these come in stream/: - precinct_barricade, precinct_checkpoint and precinct_police_tent (placeable, with collision) - precinct_tape_post (posts you place in a row get CRIME SCENE tape strung between them) - precinct_marker_1 to precinct_marker_10 (pick "Evidence markers" and they number themselves in order) - precinct_breathalyzer and precinct_print_scanner (held during tests) - precinct_radar_gun (handheld radar: /radargun or F7 → Radar) - precinct_ankle_monitor (worn on the leg) - precinct_tint_meter, precinct_drug_swab, precinct_gps_tracker and precinct_narco_pouch (held while testing / fitting a tracker) - precinct_battering_ram (door ram carried during raids) - precinct_evidence_bag, precinct_evidence_bag_full, precinct_narco_kit, precinct_zipties and precinct_spike_case (item pictures)

Item and prop pictures: the props menu, the armory and the inventory show real pictures of the in-game models. To make them, stand somewhere quiet and type /precinctimages (admins only). Every scene prop and tool item is photographed on a green screen, cut out and saved to html/img/props/ and html/img/items/. It takes a minute or two. Type restart precinct when it's done. This needs screencapture or screenshot-basic. Run it again after you add props. To redo only some, list them: /precinctimages breathalyzer tint_meter pc_evidence. To change how an item is framed, edit Config.ItemRenders in config/tools.lua (rot turns it, pitch tilts it); for a prop, add rot / pitch to its line in config/props.lua. Anything without a picture shows an icon.

Markers, tape posts, cones and flares keep placing one after another until you press Backspace. Tape shows a live preview from your last post.

Lining up hand props: type /precinctprop radarGun (or breathalyzer, scanner, tintMeter, ankle or ram). Use the arrow keys and PageUp/PageDown to move it; hold CTRL to rotate instead, and SHIFT for fine steps. ENTER copies the line, which you paste into Config.ToolProps in config/tools.lua (for ram: over its offset / rot in Config.Raids.ramProps, config/raids.lua).

Your own props: put your .ydr and .ytyp files in precinct/stream/. Add data_file 'DLC_ITYP_REQUEST' 'stream/yourfile.ytyp' to fxmanifest.lua, then add the model to config/props.lua.

Drinks and drugs from other scripts: exports.precinct:AddAlcohol(source, 0.04) and exports.precinct:AddDrug(source, 'THC'). Items listed in config/tools.lua are picked up automatically when used.

Translate everything in locales/en.lua.

Keys and commands

All keys can be changed in GTA settings, under Key Bindings, then FiveM.

Default
MDT F6 / /mdt
Police menu (radial) F7
Respond to the latest call (sets GPS) G
Radar power NUMPAD7
Radar remote F5
Lock front / rear radar NUMPAD8 / NUMPAD5
Lock plate reader NUMPAD9
Car PA (hold) B
Bodycam overlay /bodycam
Panic button /panic (bind a key in settings)
Toggle duty /duty or the duty point
Citation / arrest the closest person /fine · /jail
Clear props F7 → Scene tools → Clear my props / Clear scene, the props menu, MDT → Field tools, or /clearscene (30m), /clearscene 50, /clearscene mine, /clearscene all (command only)
Narcotics test kit /narcokit or F7 → Forensics
Crime scene camera /scenecam, the camera item, or F7 → Forensics. In the viewfinder: LMB shoot, scroll zoom, F flash, G grid, H info, RMB lower
File photos under a case /photocase 12 (no number = stop), or "Camera → this case" on the case board
UV light /uvlight, the UV light item, or F7 → Forensics. Walk up to a glowing door handle and press E to lift the print
Traffic stop (vehicle in front) F7 → Vehicle → Pull over (bind a key in settings)
Cut off your ankle monitor /cutmonitor (needs a knife)
Unit status MDT header chip, or /status 10-8 · 10-6 · 10-7 · onscene
Helicopter camera E in a helicopter. Mouse look, scroll zoom, RMB vision mode, Space lock on, G spotlight, H mark for ground units, E exit
Court (prosecutors and judges) /court · /judge for warrant review
Call the police (anyone) /911 <what's happening> · /311 <...>, or call / text 911 or 311 on the phone
Citizen portal (anyone) /records, or the Citizen app on lb-phone

Everything else is on the target (third eye) on players, vehicles and station points.

For other scripts

-- dispatch alert from any script (server)
exports.precinct:Alert({ title = 'Store robbery', code = '10-90', coords = coords, priority = 'high' })

exports.precinct:GetCopCount()   -- on-duty cops (also GlobalState.precinctCops)
exports.precinct:IsCop(source)
exports.precinct:IsCuffed(source)

Scripts made for qb-policejob keep working. Precinct answers the old events: police:server:policeAlert, police:client:CuffPlayer, police:client:EscortPlayer, the qbx_radialmenu police buttons, police:SetCopCount and the rest.

Credits

  • Precinct is made by QBₓ BØNES. Do not resell or reupload it.
  • Fonts: Google Fonts (SIL Open Font License). Icons: Font Awesome Free (CC BY 4.0 / SIL OFL).