FiveM Docs
Addons

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

Resourceesx_policejob (version 1.0.2)
Sideclient + server
Job namepolice (grades recruit, officer, sergeant, lieutenant, boss)
Societysociety_police (account, datastore and inventory)
Hard dependenciesesx_lib, es_extended, esx_billing, esx_vehicleshop
Also usedoxmysql, esx_society (boss menu, armory storage), esx_garage (impound)
Optionalesx_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 BossActions marker. 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

server.cfg
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_policejob

Turn 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.

KeyDefaultDescription
Config.DrawDistance10.0Distance at which markers are drawn.
Config.ActionVehicleDistance2.0How 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.EnablePlayerManagementtrueEnables society management (boss menu).
Config.EnableArmoryManagementfalseAdds weapon and item deposit/withdraw to the armory.
Config.EnableESXIdentitytrueShows name, date of birth, sex and height from esx_identity on ID cards and in vehicle owner lookups.
Config.EnableESXOptionalneedsfalseShows the drunk level (from esx_status) in the ID card menu.
Config.EnableLicensesfalseShows licenses during body search and enables license checks and revocation through esx_license.
Config.EnableHandcuffTimertrueUncuffs automatically after Config.HandcuffTimer.
Config.HandcuffTimer10 * 60000Auto-uncuff delay in milliseconds (10 minutes).
Config.EnableCustomPedsfalseLets officers pick a ped model from Config.CustomPeds in the cloakroom.
Config.EnableESXServicefalseRequires officers to be in service (esx_service) before using the armory, garage and F6 menu.
Config.MaxInService-1Maximum number of officers in service. -1 means no limit.
Config.EnableFinePresetsfalsetrue uses the fine_types categories, false shows a free amount and reason input.
Config.LocaleGetConvar('esx:locale', 'en')Language.
Config.OxInventoryESX.GetConfig().OxInventoryRead from es_extended, do not change.

Stations

Config.PoliceStations is a table of stations (the default one is LSPD). Each station has:

FieldDescription
BlipCoords, Sprite, Display, Scale, Colour for the map blip.
CloakroomsList of vector3 positions.
ArmoriesList of vector3 positions. The server only accepts armory actions within 8 units of one of these.
Vehicles / HelicoptersList of garages. Each has a Spawner position, an InsideShop preview position and SpawnPoints (coords, heading, radius).
BossActionsList 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 = { ... } }. components holds one price per component index of the weapon in ESX's weapon list; nil hides that component.
  • Config.AuthorizedVehicles.car[grade] and Config.AuthorizedVehicles.helicopter[grade]: list of { model = 'police3', price = n, props = { ... } }. props is optional and is merged into the stored vehicle properties.
  • Config.CustomPeds: shared entries are available to every grade, plus one list per grade. Each entry has label, maleModel, femaleModel.
  • Config.Uniforms: one entry per grade plus bullet_wear and gilet_wear, each with male and female skinchanger components.
config.lua
-- 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.

EventArgumentsServer checks
esx_policejob:handcufftargetOn-duty police, within 5 units of target. Toggles the cuffs.
esx_policejob:dragtargetOn-duty police, target is cuffed, within 5 units.
esx_policejob:putInVehicletargetOn-duty police, target is cuffed, within 5 units.
esx_policejob:OutVehicletargetOn-duty police, target is cuffed, within 8 units.
esx_policejob:confiscatePlayerItemtarget, itemType, itemName, amountOn-duty police, target cuffed and within 5 units. itemType is item_standard, item_account or item_weapon.
esx_policejob:getStockItemitemName, countOn-duty police near an armory. Withdraws from society_police.
esx_policejob:putStockItemsitemName, countOn-duty police near an armory. Deposits into society_police.
esx_policejob:impoundOwnedVehicleplatePolice 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.

CallbackArgumentsReturns
esx_policejob:getOtherPlayerDatatarget, notifyTable 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:getFineListcategoryRows from fine_types for that category (cached in memory).
esx_policejob:getVehicleInfosplate{ plate, owner? }.
esx_policejob:getArmoryWeaponsnoneWeapons stored in the society_police datastore.
esx_policejob:addArmoryWeaponweaponName, removeWeapontrue on success.
esx_policejob:removeArmoryWeaponweaponNametrue on success, gives the weapon with 500 ammo.
esx_policejob:buyWeaponweaponName, type, componentNumtype 1 buys the weapon, 2 buys a component. Price comes from Config.AuthorizedWeapons.
esx_policejob:buyJobVehiclevehicleProps, typeInserts the car into owned_vehicles with job = 'police' and a POL plate.
esx_policejob:storeNearbyVehicleplatesPlate that was stored, or false.
esx_policejob:getStockItemsnoneItems in the society_police inventory.
esx_policejob:getPlayerInventorynone{ items = ... } of the caller.

Client events

EventTriggered byEffect
esx_policejob:handcuffserverToggles the cuffed animation and control locks on the target.
esx_policejob:unrestrainserver or localRemoves cuffs. Fired automatically on spawn and when the resource stops.
esx_policejob:dragserver(copId) toggles being dragged by that officer.
esx_policejob:putInVehicleserverWarps the cuffed player into a free passenger seat of the closest vehicle (searching from the back).
esx_policejob:OutVehicleserverPulls the cuffed player out of the vehicle.

Keybinds

NameDefaultAction
police:quickactionsF6Opens the police actions menu.
police:interactEUses 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:

server/main.lua
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)
client/main.lua
if LocalPlayer.state.isHandcuffed then
    ESX.ShowNotification('You cannot do that while cuffed.')
    return
end

Fines 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 is false cannot 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 above 0, the player has enough cash, and they stand within 35 units of the garage InsideShop or Spawner.
  • ID card shows no name, date of birth or height. Config.EnableESXIdentity is true by default; if you do not run esx_identity, set it to false.
  • Impound does nothing. Impounding needs esx_garage to export impoundVehicle. Without it the call silently fails.
  • Duplicate SQL errors. See the txAdmin recipe note above.

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page