esx_policejob
Set up esx_policejob for ESX Legacy. Covers SQL, config keys, armory, job vehicles, handcuffs, fines, server events, callbacks and common issues.
esx_policejob turns the police job into a playable law-enforcement role: cloakrooms with grade uniforms, an armory where officers buy weapons, a garage for job cars and helicopters, a boss menu, and an F6 menu to search, cuff, drag, fine and impound. Install it when you want the stock ESX police department rather than writing your own.
Overview
| Resource | esx_policejob (version 1.0.2) |
| Side | client + server |
| Job name | police (grades recruit, officer, sergeant, lieutenant, boss) |
| Society | society_police (account, datastore and inventory) |
| Hard dependencies | esx_lib, es_extended, esx_billing, esx_vehicleshop |
| Also used | oxmysql, esx_society (boss menu, armory storage), esx_garage (impound) |
| Optional | esx_identity, esx_license, esx_service, esx_status |
On start the server registers the society with esx_society:registerSociety and, when Config.EnableESXService is on and Config.MaxInService is not -1, activates a service limit through esx_service.
What officers can do
- Cloakroom: switch between civilian clothes and the uniform for their grade, add a bulletproof vest or a high-visibility vest, and (optionally) pick a custom ped.
- Armory: buy the weapons listed for their grade. With armory management enabled they can also deposit and withdraw weapons and items from the shared police storage.
- Garage: buy job cars or helicopters for their grade, take them out, and store them again.
- F6 menu:
- Citizen interaction: ID card, body search, handcuff, drag, put in vehicle, take out of vehicle, fine, unpaid bills, and license check (when licenses are enabled).
- Vehicle interaction: vehicle info, lockpick, impound, search the plate database.
- Object spawner: cones, barriers, spike strips, boxes and a cash crate.
- Boss menu: managed by esx_society at the
BossActionsmarker. Money washing is disabled and the uniform editor is enabled.
Installation
Import the SQL
Run esx_policejob.sql. It adds the society_police rows to addon_account, datastore and addon_inventory, creates the police job with five grades, and creates and fills the fine_types table.
Translated variants live in localization/<lang>_esx_policejob.sql (de, en, es, fi, fr, it, nl, pl, sr). Import only one of them.
Start it after its dependencies
ensure oxmysql
ensure es_extended
ensure esx_lib
ensure esx_addonaccount
ensure esx_addoninventory
ensure esx_datastore
ensure esx_society
ensure esx_billing
ensure esx_vehicleshop
ensure esx_policejobTurn on the optional integrations
Set Config.EnableESXIdentity, Config.EnableLicenses, Config.EnableESXService and Config.EnableESXOptionalneeds to match the resources you actually run.
txAdmin recipe installs
The official ESX recipe (legacy.sql) already contains the police job, its society rows and the fine_types table. If you used the recipe, do not import esx_policejob.sql again. It fails with duplicate key and "table already exists" errors.
Configuration
All options are in config.lua.
| Key | Default | Description |
|---|---|---|
Config.DrawDistance | 10.0 | Distance at which markers are drawn. |
Config.ActionVehicleDistance | 2.0 | How close a vehicle must be for vehicle actions in the F6 menu. |
Config.MarkerType | { Cloakrooms = 20, Armories = 21, BossActions = 22, Vehicles = 36, Helicopters = 34 } | Marker type per station point. |
Config.MarkerSize | { x = 1.5, y = 1.5, z = 0.5 } | Marker size. |
Config.MarkerColor | { r = 50, g = 50, b = 204 } | Marker color. |
Config.EnablePlayerManagement | true | Enables society management (boss menu). |
Config.EnableArmoryManagement | false | Adds weapon and item deposit/withdraw to the armory. |
Config.EnableESXIdentity | true | Shows name, date of birth, sex and height from esx_identity on ID cards and in vehicle owner lookups. |
Config.EnableESXOptionalneeds | false | Shows the drunk level (from esx_status) in the ID card menu. |
Config.EnableLicenses | false | Shows licenses during body search and enables license checks and revocation through esx_license. |
Config.EnableHandcuffTimer | true | Uncuffs automatically after Config.HandcuffTimer. |
Config.HandcuffTimer | 10 * 60000 | Auto-uncuff delay in milliseconds (10 minutes). |
Config.EnableCustomPeds | false | Lets officers pick a ped model from Config.CustomPeds in the cloakroom. |
Config.EnableESXService | false | Requires officers to be in service (esx_service) before using the armory, garage and F6 menu. |
Config.MaxInService | -1 | Maximum number of officers in service. -1 means no limit. |
Config.EnableFinePresets | false | true uses the fine_types categories, false shows a free amount and reason input. |
Config.Locale | GetConvar('esx:locale', 'en') | Language. |
Config.OxInventory | ESX.GetConfig().OxInventory | Read from es_extended, do not change. |
Stations
Config.PoliceStations is a table of stations (the default one is LSPD). Each station has:
| Field | Description |
|---|---|
Blip | Coords, Sprite, Display, Scale, Colour for the map blip. |
Cloakrooms | List of vector3 positions. |
Armories | List of vector3 positions. The server only accepts armory actions within 8 units of one of these. |
Vehicles / Helicopters | List of garages. Each has a Spawner position, an InsideShop preview position and SpawnPoints (coords, heading, radius). |
BossActions | List of vector3 positions for the boss menu. |
Grade-based tables
These tables are keyed by grade name (recruit, officer, sergeant, lieutenant, boss). If you rename grades in the database, rename the keys too.
Config.AuthorizedWeapons[grade]: list of{ weapon = 'WEAPON_X', price = n, components = { ... } }.componentsholds one price per component index of the weapon in ESX's weapon list;nilhides that component.Config.AuthorizedVehicles.car[grade]andConfig.AuthorizedVehicles.helicopter[grade]: list of{ model = 'police3', price = n, props = { ... } }.propsis optional and is merged into the stored vehicle properties.Config.CustomPeds:sharedentries are available to every grade, plus one list per grade. Each entry haslabel,maleModel,femaleModel.Config.Uniforms: one entry per grade plusbullet_wearandgilet_wear, each withmaleandfemaleskinchanger components.
-- Let recruits buy a basic cruiser
Config.AuthorizedVehicles.car.recruit = {
{ model = 'police', price = 5000 },
}The server rejects any vehicle whose configured price is 0. To hand out free cars, use a price of 1 or extend the script.
Server events
All of these are network events that the client triggers. Every handler checks that the caller has the police job and is not off duty, and most also check distance. Do not call them from other resources unless you need the same behavior.
| Event | Arguments | Server checks |
|---|---|---|
esx_policejob:handcuff | target | On-duty police, within 5 units of target. Toggles the cuffs. |
esx_policejob:drag | target | On-duty police, target is cuffed, within 5 units. |
esx_policejob:putInVehicle | target | On-duty police, target is cuffed, within 5 units. |
esx_policejob:OutVehicle | target | On-duty police, target is cuffed, within 8 units. |
esx_policejob:confiscatePlayerItem | target, itemType, itemName, amount | On-duty police, target cuffed and within 5 units. itemType is item_standard, item_account or item_weapon. |
esx_policejob:getStockItem | itemName, count | On-duty police near an armory. Withdraws from society_police. |
esx_policejob:putStockItems | itemName, count | On-duty police near an armory. Deposits into society_police. |
esx_policejob:impoundOwnedVehicle | plate | Police job, vehicle with that plate within 8 units. Calls exports['esx_garage']:impoundVehicle(plate). |
Security
confiscatePlayerItem moves items, money and weapons between players, so it is the event cheaters target first. The current version validates job, duty, distance and cuff state on the server. If you fork the script or add your own actions, keep those checks on the server side and never trust a target ID or amount sent by the client.
Server callbacks
Callbacks are registered with xLib.callback.registerCompat, so they work with both xLib.callback and the classic ESX.TriggerServerCallback.
| Callback | Arguments | Returns |
|---|---|---|
esx_policejob:getOtherPlayerData | target, notify | Table with name, job, grade, inventory, accounts, weapons, plus dob, height, sex (identity), drunk (status) and licenses (license) when enabled. Empty table unless the target is cuffed and within 5 units. |
esx_policejob:getFineList | category | Rows from fine_types for that category (cached in memory). |
esx_policejob:getVehicleInfos | plate | { plate, owner? }. |
esx_policejob:getArmoryWeapons | none | Weapons stored in the society_police datastore. |
esx_policejob:addArmoryWeapon | weaponName, removeWeapon | true on success. |
esx_policejob:removeArmoryWeapon | weaponName | true on success, gives the weapon with 500 ammo. |
esx_policejob:buyWeapon | weaponName, type, componentNum | type 1 buys the weapon, 2 buys a component. Price comes from Config.AuthorizedWeapons. |
esx_policejob:buyJobVehicle | vehicleProps, type | Inserts the car into owned_vehicles with job = 'police' and a POL plate. |
esx_policejob:storeNearbyVehicle | plates | Plate that was stored, or false. |
esx_policejob:getStockItems | none | Items in the society_police inventory. |
esx_policejob:getPlayerInventory | none | { items = ... } of the caller. |
Client events
| Event | Triggered by | Effect |
|---|---|---|
esx_policejob:handcuff | server | Toggles the cuffed animation and control locks on the target. |
esx_policejob:unrestrain | server or local | Removes cuffs. Fired automatically on spawn and when the resource stops. |
esx_policejob:drag | server | (copId) toggles being dragged by that officer. |
esx_policejob:putInVehicle | server | Warps the cuffed player into a free passenger seat of the closest vehicle (searching from the back). |
esx_policejob:OutVehicle | server | Pulls the cuffed player out of the vehicle. |
Keybinds
| Name | Default | Action |
|---|---|---|
police:quickactions | F6 | Opens the police actions menu. |
police:interact | E | Uses the marker you are standing in (cloakroom, armory, garage, boss menu). |
Both are registered through xLib.addKeybind, so players can rebind them under Settings → Key Bindings → FiveM.
Integration tips
Check whether someone is cuffed before letting them use your own features:
RegisterNetEvent('myphone:open', function()
local src = source
if Player(src).state.isHandcuffed then
return -- cuffed players cannot use the phone
end
TriggerClientEvent('myphone:show', src)
end)if LocalPlayer.state.isHandcuffed then
ESX.ShowNotification('You cannot do that while cuffed.')
return
endFines are sent with esx_billing:sendBill to society_police, so paid fines land in the police society account. To pay officers a commission or log fines, hook into esx_billing rather than this resource.
Common issues
- "Off duty" notification everywhere. The script respects
job.onDuty. A player whose duty flag isfalsecannot use the armory, garage or F6 menu. - Nothing happens when buying a car. Check that the grade has entries in
Config.AuthorizedVehicles, the price is above0, the player has enough cash, and they stand within 35 units of the garageInsideShoporSpawner. - ID card shows no name, date of birth or height.
Config.EnableESXIdentityistrueby default; if you do not run esx_identity, set it tofalse. - Impound does nothing. Impounding needs
esx_garageto exportimpoundVehicle. Without it the call silently fails. - Duplicate SQL errors. See the txAdmin recipe note above.
Related
Frequently asked questions
Independent documentation
Last updated on
esx_pausemenu
esx_pausemenu replaces the GTA pause screen with a branded ESX Legacy NUI menu showing character, money, job and links. Install and config guide.
esx_property
esx_property lets ESX Legacy players buy, furnish and share houses with keys, garages, CCTV, raids and a real estate job. Setup, config, commands and exports.