Agency Docs
QBESXStandalone

Agency-Drugs Configuration

The complete drug system for FiveM in one script.

v1.0.0Paid5 PagesFrom 01.11.2026

01Configuration

Quick Installation · config.lua · Agency-Drugs

Download config.lua

--[[ ╔══════════════════════════════════════════════════════════════════════╗ ║ AGENCY DRUGS - CONFIGURATION ║ ║ (c) Agency Scripts ║ ╚══════════════════════════════════════════════════════════════════════╝ Almost everything is set up IN GAME with /drugsadmin: routes, fields, pickup points, labs, recipes, pushers, drugs, prices, chances, times, police rules, blips, selling, narcos, auctions, effects. This file only holds what has to be known before the server starts or what never changes while it runs. CONTENTS 1. Core Framework, language, permissions, commands 2. Money & Quality Where drug money goes, item quality 3. Police & Logs Police jobs, dispatch, Discord webhooks 4. Scripts Agency Gangs, Phone, Pad, Housing, Blackmarket 5. Technical Draw distances, keys, performance 6. First start Values written to the database once, then edited in game Texts players see live in locales/ (copy _template.lua for a new language). ]] Config = {} --============================================================================== -- 1 · CORE --============================================================================== -- 'auto' finds QBCore (qb-core), QBox (qbx_core) or ESX (es_extended) by -- itself and runs standalone when none of them is installed. -- 'qbcore' | 'esx' | 'standalone' force one of them. Config.Framework = 'auto' -- Language file from locales/. 25 languages ship with the script. Config.Locale = 'en' -- Extra console output for support cases. Keep false on a live server. Config.Debug = false -- Heading on every notification. Config.NotifyTitle = 'Drugs' -- Notifications. 'auto' picks the first one that is running: -- Agency-Notify > ox_lib > QBCore / ESX > GTA notification. -- 'agency' | 'ox' | 'qbcore' | 'esx' | 'native' force one of them. -- Agency-Notify, matching design: https://agencyscripts.dev/en/product/notify Config.Notify = 'auto' -- Progress bar. 'auto' picks the first one that is running: -- Agency-Progressbar > ox_lib > the bar built into this script. -- 'agency' | 'ox' | 'builtin' force one of them. -- Agency-Progressbar, matching design: https://agencyscripts.dev/en/product/progressbar Config.Progressbar = 'auto' -- Accent colour of every menu and HUD. Gold is the Agency default. -- Any hex colour works, e.g. '#35d6a6' for green or '#e04646' for red. Config.AccentColor = '#e2b649' -- Who counts as an admin for /drugsadmin. ACE 'agency.drugs' always works too. Config.AdminGroups = { 'admin', 'god', 'superadmin' } Config.Commands = { admin = 'drugsadmin', -- opens the admin menu (routes, balancing, import) sell = 'selldrugs', -- street selling on / off, also starts plane and boat runs craft = 'drugcraft', -- pocket crafting (recipes that need no lab, e.g. rolling joints) } -- Standalone (no framework): money and admins come from these hooks. Config.Standalone = { admins = {}, -- licence identifiers getMoney = nil, -- function(src, account) return 0 end addMoney = nil, -- function(src, account, amount) return true end removeMoney = nil, -- function(src, account, amount) return true end } --============================================================================== -- 2 · MONEY & QUALITY --============================================================================== -- Where the money from selling drugs goes. -- type = 'account' a framework account: 'black_money' (ESX), 'cash', 'bank' -- type = 'item' an item, e.g. 'markedbills' or 'black_money' (ox_inventory) Config.Reward = { type = 'account', name = 'black_money' } -- QBCore has no black_money account by default. If it is missing, the -- script pays in this account instead and warns once in the console. Config.RewardFallback = 'cash' Config.Currency = { symbol = '$', position = 'before' } Config.Quality = { enabled = true, -- Inventories without item metadata (most ESX inventories) treat every -- drug as this quality. noMetadata = 100, } --============================================================================== -- 3 · POLICE & LOGS --============================================================================== Config.Police = { jobs = { 'police', 'sheriff', 'state' }, -- 'auto' picks ps-dispatch, cd_dispatch, tk_dispatch, qs-dispatch, core_dispatch -- or falls back to a blip for every officer on duty. dispatch = 'auto', } -- Discord webhooks. Leave empty to disable. One URL can serve every category. Config.Webhooks = { default = '', harvest = '', -- fields and pickup points labs = '', -- cooking, failed batches, fires sales = '', -- street, pushers, narcos, plane, boat, auctions admin = '', -- every change in /drugsadmin and every import } --============================================================================== -- 4 · SCRIPTS --============================================================================== Config.Integrations = { -- Agency Gangs: bonus for selling in your own turf, a share of every sale -- goes to the gang's dirty money vault, the owning gang is warned about -- foreign dealers. Percentages are set in game (Balancing > Gangs). gangs = true, -- The Dealer app on Agency Phone and Agency Pad: market prices, narcos, -- auctions and the player market. Offered in the App Store of both devices. phone = true, pad = true, -- true = the app is on every phone and pad from the start, false = players -- install it from the App Store themselves. appPreinstalled = false, } -- Player market in the Dealer app (tab "Trade"): players post offers ("I sell") -- and requests ("I buy"), find each other under anonymous dealer names, chat and -- meet for the hand over. Goods and money stay in escrow until then, so nobody -- can be scammed. Paid in the same money as street sales (Config.Reward). Config.Market = { enabled = true, maxListings = 5, -- open offers + requests per character maxDeals = 5, -- deals running at once per character listingHours = 24, -- listings left after this go back to the owner dealHours = 6, -- a deal not handed over by then is called off, all goes back priceRange = { 0.25, 4.0 }, -- allowed price per unit, as a multiple of the drug's base price fee = 5, -- % of every sale the market keeps (money sink), 0 = none handoverDistance = 4.0, -- metres between both players for the hand over alertChance = 10, -- % chance the police get a call at a hand over policeCanUse = false, -- officers on duty see the tab locked } --============================================================================== -- 5 · TECHNICAL --============================================================================== Config.Keys = { interact = 38, -- E } -- Distances in metres. -- Batches and continuous cooking. How many batches a recipe allows at once is set per -- recipe in /drugsadmin (1 = classic single batch). Labs can keep cooking on their own. Config.Cooking = { defaultMaxBatches = 3, -- for recipes that do not set their own limit extraBatchTime = 0.75, -- every extra batch adds 75 % of the recipe time (3 batches = 2.5x time, 3x output) continuous = true, -- labs offer "keep cooking" unless switched off per lab pocketContinuous = false,-- the same for pocket crafting (rolling joints and the like) -- A wrong mix is dangerous: every unit away from the perfect amounts adds fail chance, -- and from `explodeFrom` units off the batch blows up (gas explosion, fire, smoke). wrongMix = { failPerOff = 6, -- % extra fail chance per unit off perfect maxFail = 85, -- never more than this explodeFrom = 4, -- units off (summed over all ingredients) that make a failed batch explode, 0 = never }, -- Secret recipes: players first have to find the perfect amounts. Once a character hits -- every perfect amount, the recipe is learned for good and shown from then on. discovery = { enabled = true, feedback = 'hint', -- after a batch: 'hint' = more / less / right per ingredient, 'vague' = only how many are right, 'none' pocket = false, -- pocket recipes (rolling joints) are always known }, } -- ===================================================== -- HOME GROWING — plant seeds in pots at home, water, fertilise, harvest -- ===================================================== Config.Growing = { enabled = true, -- Where pots may stand: -- 'property' = only on or in a house the player can use (Agency-Housing, found by itself) -- 'interior' = only inside buildings, 'anywhere' = everywhere outdoors and indoors where = 'property', maxPlants = 6, -- per character minDistance = 1.2, -- between two pots waterDrain = 12, -- % water lost per 10 minutes deathAfter = 45, -- minutes at 0 % water before the plant dies policeCanDestroy = true, -- officers on duty can pull plants -- Items. The shop below sells them, every name can be changed to fit your inventory. items = { pot = { name = 'drug_pot', label = 'Plant Pot', weight = 800 }, water = { name = 'drug_water', label = 'Watering Can', weight = 500, fills = 60 }, fertilizer = { name = 'drug_fertilizer', label = 'Fertilizer', weight = 300, bonus = 15 }, }, -- One entry per seed. growMinutes is the time from seed to harvest with full water. seeds = { { item = 'weed_seed', label = 'Cannabis Seed', weight = 10, growMinutes = 40, output = 'cannabis_leaf', amount = { 6, 10 }, quality = { 60, 95 }, props = { 'bkr_prop_weed_01_small_01b', 'bkr_prop_weed_med_01b', 'bkr_prop_weed_lrg_01b' } }, { item = 'coca_seed', label = 'Coca Seed', weight = 10, growMinutes = 55, output = 'coca_leaf', amount = { 5, 8 }, quality = { 55, 90 }, props = { 'prop_plant_01a', 'prop_plant_01b', 'prop_plant_int_03a' } }, }, } -- ===================================================== -- ADDICTION — tolerance, withdrawal, detox and drug tests -- ===================================================== Config.Addiction = { enabled = true, perUse = 8, -- addiction points per dose (0 to 100), per drug effect below perDrug = { weed = 5, cocaine = 10, meth = 14, ketamine = 9, lean = 7, heroin = 16 }, decayPerHour = 6, -- points lost per hour clean tolerance = 0.5, -- at 100 points a dose works only half as strong and long withdrawalFrom = 40, -- points from which a craving starts withdrawalAfter = 25, -- minutes after the last dose withdrawalHealth = 1, -- health lost every 30 s in withdrawal (0 = only the screen) minHealth = 120, -- withdrawal never takes health below this detoxItem = { name = 'drug_detox', label = 'Detox Kit', weight = 200, removes = 60 }, -- /drugtest [id] for these jobs, shows which drugs were taken in the last hours drugTest = { enabled = true, command = 'drugtest', jobs = { 'police', 'sheriff', 'ambulance' }, hours = 6, distance = 3.0 }, } -- ===================================================== -- GROW SHOP — seeds, pots and everything for home growing -- ===================================================== Config.Shop = { enabled = true, label = 'Smoke on the Water', ped = 'a_m_y_hippy_01', -- the real dispensary building on Vespucci Beach coords = vector4(-1171.42, -1571.06, 4.66, 125.0), blip = { enabled = true, sprite = 140, colour = 2, scale = 0.8 }, currency = 'cash', -- 'cash' | 'bank' | or the drug money of Config.Reward with 'reward' items = { { item = 'weed_seed', price = 60 }, { item = 'coca_seed', price = 110 }, { item = 'drug_pot', price = 150 }, { item = 'drug_water', price = 40 }, { item = 'drug_fertilizer', price = 90 }, { item = 'drug_detox', price = 650 }, }, } -- Drug kitchens. A lab with an interior is a door outside: press E, the screen fades and -- you stand in a full GTA lab (Bikers DLC, works with or without bob74_ipl). The recipes are -- cooked at the stations inside. Pick the interior per lab in /drugsadmin. Config.LabInteriors = { instanced = true, -- every lab gets its own copy of the room (routing bucket), labs never share a kitchen meth = { entry = vector4(998.70, -3200.67, -38.99, 270.0), stations = { vector4(1005.77, -3200.40, -38.52, 180.0) }, sets = { 'meth_lab_upgrade', 'meth_lab_setup', 'meth_lab_production', 'meth_lab_security_high' }, off = { 'meth_lab_empty', 'meth_lab_basic' }, -- would overlap the upgraded equipment -- The cook from GTA Online: canister, acid, clipboard and pencil, placed exactly at the cooker. scene = { origin = vector3(1010.656, -3198.445, -38.925), rot = vector3(0.0, 0.0, 0.0), dict = 'anim@amb@business@meth@meth_monitoring_cooking@cooking@', anim = 'chemical_pour_short_cooker', props = { { 'bkr_prop_meth_ammonia', 'chemical_pour_short_ammonia' }, { 'bkr_prop_meth_sacid', 'chemical_pour_short_sacid' }, { 'bkr_prop_fakeid_clipboard_01a', 'chemical_pour_short_clipboard' }, { 'bkr_prop_fakeid_penclipboard', 'chemical_pour_short_pencil' } } }, steam = { fx = 'ent_amb_steam_vent_open_hvy', offset = vector3(-0.2, 0.75, 0.35), scale = 1.3 }, }, cocaine = { entry = vector4(1088.68, -3187.68, -38.99, 180.0), stations = { vector4(1093.17, -3194.86, -38.99, 180.0), vector4(1101.81, -3193.73, -38.99, 0.0) }, sets = { 'set_up', 'equipment_upgrade', 'production_upgrade', 'table_equipment_upgrade', 'coke_press_upgrade', 'security_high', 'coke_cut_01', 'coke_cut_02', 'coke_cut_03', 'coke_cut_04', 'coke_cut_05' }, off = { 'equipment_basic', 'production_basic', 'table_equipment', 'security_low' }, steam = { fx = 'ent_amb_steam_vent_rnd', offset = vector3(0.0, 0.6, 0.0), scale = 0.8 }, }, weed = { entry = vector4(1066.01, -3183.38, -39.16, 90.0), stations = { vector4(1039.36, -3205.86, -38.17, 90.0), vector4(1032.71, -3203.94, -38.18, 90.0) }, sets = { 'weed_upgrade_equip', 'weed_drying', 'weed_production', 'weed_security_upgrade', 'weed_chairs', 'weed_growtha_stage3', 'weed_growthb_stage3', 'weed_growthc_stage3', 'weed_growthd_stage3', 'weed_growthe_stage3', 'weed_growthf_stage3', 'weed_growthg_stage3', 'weed_growthh_stage3', 'weed_growthi_stage3', 'weed_hosea', 'weed_hoseb', 'weed_hosec', 'weed_hosed', 'weed_hosee', 'weed_hosef', 'weed_hoseg', 'weed_hoseh', 'weed_hosei', 'light_growtha_stage23_upgrade', 'light_growthb_stage23_upgrade', 'light_growthc_stage23_upgrade', 'light_growthd_stage23_upgrade', 'light_growthe_stage23_upgrade', 'light_growthf_stage23_upgrade', 'light_growthg_stage23_upgrade', 'light_growthh_stage23_upgrade', 'light_growthi_stage23_upgrade' }, off = { 'weed_standard_equip', 'weed_low_security' }, }, } Config.Distances = { streamPoints = 120.0, -- fields, labs and peds exist only within this range marker = 25.0, -- markers are drawn within this range interact = 2.0, fieldPlant = 1.6, -- how close you must be to a plant to harvest it } --============================================================================== -- 6 · FIRST START --============================================================================== -- On the very first start the script writes the 5 default routes and these -- balancing values into the database. After that they are edited in game -- with /drugsadmin and this table is no longer read. -- To start over: /drugsadmin > Balancing > Reset to defaults. Config.InstallDefaultRoutes = true Config.Defaults = { blips = { enabled = true, -- master switch, handy for police on serious servers fields = true, pickups = true, labs = true, pushers = true, narcos = true, auctions = true, }, police = { -- Every officer on duty raises sale prices by this %, up to maxBonus. bonusPerCop = 4, maxBonus = 40, }, quality = { perfectBonus = 15, -- quality points for hitting every perfect amount in a lab missPenalty = 6, -- quality points lost per unit away from perfect priceMin = 50, -- % of the price at 0 % quality priceMax = 140, -- % of the price at 100 % quality }, street = { enabled = true, minPolice = 0, acceptChance = 70, -- % robChance = 4, -- % the buyer robs you and runs alertChance = 12, -- % the buyer calls the police amountMin = 1, amountMax = 4, cooldown = 6, -- seconds between two buyers priceMult = 100, -- % of the base price }, market = { enabled = true, dropPerSale = 1.5, -- % the price in that district falls per unit sold recoverPerMin = 0.8, -- % it recovers per minute minMult = 55, -- never below this % of the base price maxMult = 125, -- rises up to this % when nobody sells there }, narcos = { enabled = true, minPolice = 0, moveEvery = 30, -- minutes until the buyer moves on priceMult = 135, minAmount = 10, maxAmount = 200, alertChance = 20, }, plane = { enabled = true, minPolice = 0, minHeight = 120.0, -- metres above ground interval = 6, -- seconds per drop perDrop = 3, -- units per drop priceMult = 125, alertChance = 30, -- % once per run }, boat = { enabled = true, minPolice = 0, minShore = 250.0, -- metres from the coast interval = 6, perDrop = 3, priceMult = 120, alertChance = 25, }, auctions = { enabled = false, -- off by default, admins can switch it on in the panel every = 60, -- minutes between two auctions duration = 10, -- minutes an auction runs priceMult = 175, -- start price, falls to 110 % as the buyer fills up amountMin = 20, amountMax = 60, }, harvest = { antiAfk = true, -- you must move between two harvests at a pickup point cooldown = 2, -- seconds between two harvests }, labs = { smoke = true, -- chimney smoke while a batch cooks fireDamage = true, -- a failed batch with fire hurts players nearby }, effects = { enabled = true, overdose = true, -- too much in a short time knocks you out overdoseLimit = 4, -- doses within 5 minutes }, gangs = { ownTurfBonus = 15, -- % more when you sell in your own gang's turf gangShare = 10, -- % of every sale goes to the gang's dirty money vault warnOwners = true, }, limits = { maxSellPerHour = 0, -- units per player per hour, 0 = no limit }, }

02SQL File

Optional: the resource creates these tables on its own when it starts. Import this file only if you set up the database by hand:

-- ===================================================== -- AGENCY DRUGS — optional SQL -- The script creates its own tables on the first start (agency_drugs_*). -- You only need this file on ESX: it adds the default items to the items table. -- QBCore / QBox add the items by themselves at runtime, ox_inventory uses -- the snippet in README.md. -- ===================================================== INSERT IGNORE INTO `items` (`name`, `label`, `weight`) VALUES ('cannabis_leaf', 'Cannabis Leaf', 1), ('coca_leaf', 'Coca Leaf', 1), ('solvent', 'Solvent', 1), ('pseudoephedrine', 'Pseudoephedrine', 1), ('sodium_hydroxide', 'Sodium Hydroxide', 1), ('ammonium_nitrate', 'Ammonium Nitrate', 1), ('ketamine_raw', 'Raw Ketamine', 1), ('codeine', 'Codeine Syrup', 1), ('cherry', 'Cherries', 1), ('weed_bag', 'Weed Bag', 1), ('joint', 'Joint', 1), ('cocaine_bag', 'Cocaine Bag', 1), ('meth_bag', 'Meth Bag', 1), ('ketamine_pill', 'Ketamine Pill', 1), ('lean_cup', 'Lean', 1);

Still stuck after this page? Our support team takes it from here.