Skip to Content
QBCore docs – powered by Nextra 4
ResourcesQB-Drugs - Substance System

QB-Drugs - Substance System

The qb-drugs resource provides a controlled substance system for QBCore servers, featuring drug production, distribution networks, and law enforcement interactions.

This resource simulates fictional drug mechanics for roleplay purposes only. Real-world drug use is dangerous and illegal.

Overview

QB-Drugs creates roleplay scenarios involving controlled substances with production chains, distribution networks, and law enforcement consequences. The system emphasizes roleplay over gameplay mechanics.

Key Features

  • Production Systems: Multi-stage manufacturing processes
  • Distribution Networks: Supply chain management
  • Quality Systems: Product purity and effects
  • Law Enforcement: Police investigations and seizures
  • Health Effects: Simulated consequences and addiction
  • Economic Impact: Market dynamics and pricing
  • Territory Control: Area-based operations
  • Risk vs Reward: Balanced risk/profit ratios

Installation

Prerequisites

  • QBCore Framework
  • qb-target (for interaction system)
  • qb-menu (for drug menus)
  • qb-inventory (for drug items)
  • qb-policejob (for law enforcement)

Installation Steps

  1. Download the Resource
cd resources/[qb] git clone https://github.com/qbcore-framework/qb-drugs.git
  1. Database Setup
-- Drug system tables CREATE TABLE IF NOT EXISTS `drug_labs` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` varchar(50) DEFAULT NULL, `coords` varchar(255) DEFAULT NULL, `owner` varchar(50) DEFAULT NULL, `production_rate` float DEFAULT 1.0, `last_production` timestamp DEFAULT current_timestamp(), `security_level` int(11) DEFAULT 0, PRIMARY KEY (`id`) ); CREATE TABLE IF NOT EXISTS `drug_seizures` ( `id` int(11) NOT NULL AUTO_INCREMENT, `citizenid` varchar(50) DEFAULT NULL, `officer` varchar(50) DEFAULT NULL, `drugs_seized` longtext DEFAULT NULL, `location` varchar(255) DEFAULT NULL, `timestamp` timestamp DEFAULT current_timestamp(), PRIMARY KEY (`id`) );
  1. Add Items to qb-core/shared/items.lua
-- Raw Materials (Legal) ['chemical_supplies'] = { ['name'] = 'chemical_supplies', ['label'] = 'Chemical Supplies', ['weight'] = 500, ['type'] = 'item', ['image'] = 'chemical_supplies.png', ['unique'] = false, ['useable'] = false, ['shouldClose'] = false, ['combinable'] = nil, ['description'] = 'Laboratory chemical supplies' }, -- Processed Items (Illegal) ['processed_product'] = { ['name'] = 'processed_product', ['label'] = 'Processed Product', ['weight'] = 100, ['type'] = 'item', ['image'] = 'processed_product.png', ['unique'] = false, ['useable'] = true, ['shouldClose'] = true, ['combinable'] = nil, ['description'] = 'Processed chemical product' }
  1. Add to server.cfg
ensure qb-drugs

Configuration

Basic Configuration

Config = {} -- General Settings Config.UseTarget = true Config.ProductionTime = 300000 -- 5 minutes Config.SeizureChance = 0.15 -- 15% chance during police interaction -- Production Locations Config.Labs = { ["chemistry"] = { label = "Chemistry Lab", coords = vector3(3536.5, 3662.8, 28.1), required_items = {"chemical_supplies", "lab_equipment"}, output_item = "processed_product", production_time = 300, -- seconds security_features = {"camera", "alarm", "reinforced_door"} }, ["processing"] = { label = "Processing Plant", coords = vector3(2433.8, 4969.2, 42.3), required_items = {"raw_materials", "processing_equipment"}, output_item = "refined_product", production_time = 600, capacity = 50 } } -- Market Economics Config.Economics = { base_prices = { ["processed_product"] = {min = 500, max = 800}, ["refined_product"] = {min = 1200, max = 1800} }, demand_factors = { time_of_day = true, police_presence = true, market_saturation = true }, risk_multipliers = { low_security = 1.0, medium_security = 1.3, high_security = 1.6 } }

Law Enforcement Integration

-- Police Investigation System Config.Investigation = { evidence_types = { "chemical_residue", "equipment_traces", "financial_records", "communication_logs" }, investigation_time = 1800, -- 30 minutes warrant_requirements = { evidence_count = 3, judge_approval = true, probable_cause = true } } -- Seizure and Penalties Config.Penalties = { possession = { fine_range = {5000, 15000}, jail_time = {300, 900}, -- 5-15 minutes record_type = "misdemeanor" }, distribution = { fine_range = {15000, 50000}, jail_time = {1800, 3600}, -- 30-60 minutes record_type = "felony" }, manufacturing = { fine_range = {50000, 150000}, jail_time = {3600, 7200}, -- 1-2 hours record_type = "felony", asset_forfeiture = true } }

API Reference

Server Exports

StartProduction

Begin production process at a lab.

local success = exports['qb-drugs']:StartProduction(source, labType, materials) -- Parameters: -- source: Player server ID -- labType: Type of production facility -- materials: Required materials table

ProcessSeizure

Handle drug seizure by police.

exports['qb-drugs']:ProcessSeizure(suspectId, officerId, evidence) -- Parameters: -- suspectId: Suspect player ID -- officerId: Officer player ID -- evidence: Seized items table

GetMarketPrice

Calculate current market price for products.

local price = exports['qb-drugs']:GetMarketPrice(productType, quantity) -- Returns current market value

Events

Server Events

-- Production started RegisterNetEvent('qb-drugs:server:startProduction', function(labId, productType) -- Handle production start end) -- Police raid initiated RegisterNetEvent('qb-drugs:server:policeRaid', function(location, warrantId) -- Handle police raid end) -- Market transaction RegisterNetEvent('qb-drugs:server:marketTransaction', function(buyerId, sellerId, product, quantity) -- Handle market sales end)

Usage Examples

Production System Implementation

-- Production facility management RegisterNetEvent('qb-drugs:client:startProduction', function(labType) local player = QBCore.Functions.GetPlayerData() local labConfig = Config.Labs[labType] -- Check required materials local hasMaterials = true for i = 1, #labConfig.required_items do local item = labConfig.required_items[i] if not QBCore.Functions.HasItem(item) then hasMaterials = false break end end if not hasMaterials then QBCore.Functions.Notify("Missing required materials", "error") return end -- Start production with progress bar QBCore.Functions.Progressbar("drug_production", "Processing materials...", labConfig.production_time * 1000, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = "amb@world_human_clipboard@male@base", anim = "base", }, {}, {}, function() -- Production completed TriggerServerEvent('qb-drugs:server:completeProduction', labType) end, function() QBCore.Functions.Notify("Production cancelled", "error") end) end) -- Server-side production completion RegisterNetEvent('qb-drugs:server:completeProduction', function(labType) local src = source local player = QBCore.Functions.GetPlayer(src) local labConfig = Config.Labs[labType] if not player then return end -- Remove required materials for i = 1, #labConfig.required_items do local item = labConfig.required_items[i] player.Functions.RemoveItem(item, 1) end -- Calculate output based on quality factors local baseOutput = 1 local qualityMultiplier = math.random(80, 120) / 100 -- 0.8 to 1.2 local finalOutput = math.floor(baseOutput * qualityMultiplier) -- Give product to player player.Functions.AddItem(labConfig.output_item, finalOutput, false, { quality = math.floor(qualityMultiplier * 100), production_date = os.date("%Y-%m-%d %H:%M:%S"), lab_type = labType }) TriggerClientEvent('QBCore:Notify', src, 'Production completed! Quality: ' .. math.floor(qualityMultiplier * 100) .. '%', 'success') -- Log production for investigations LogProduction(player.PlayerData.citizenid, labType, finalOutput) end)

Law Enforcement Investigation System

-- Police drug investigation tools RegisterNetEvent('qb-drugs:client:searchForEvidence', function() local player = QBCore.Functions.GetPlayerData() if player.job.name ~= "police" then QBCore.Functions.Notify("Police access only", "error") return end local coords = GetEntityCoords(PlayerPedId()) QBCore.Functions.Progressbar("searching_evidence", "Searching for evidence...", 15000, false, true, { disableMovement = true, disableCarMovement = true, disableMouse = false, disableCombat = true, }, { animDict = "amb@world_human_gardener_plant@male@base", anim = "base", }, {}, {}, function() TriggerServerEvent('qb-drugs:server:searchEvidence', coords) end) end) -- Server-side evidence processing RegisterNetEvent('qb-drugs:server:searchEvidence', function(coords) local src = source local player = QBCore.Functions.GetPlayer(src) if player.PlayerData.job.name ~= "police" then return end -- Check for nearby drug activity evidence local evidenceFound = false local evidenceTypes = {} -- Search recent production logs near this location local recentActivity = MySQL.query.await('SELECT * FROM drug_production_logs WHERE ABS(SUBSTRING_INDEX(coords, ",", 1) - ?) < 50 AND ABS(SUBSTRING_INDEX(SUBSTRING_INDEX(coords, ",", 2), ",", -1) - ?) < 50 AND timestamp > DATE_SUB(NOW(), INTERVAL 24 HOUR)', { coords.x, coords.y }) if #recentActivity > 0 then evidenceFound = true table.insert(evidenceTypes, {\n type = \"chemical_residue\",\n description = \"Chemical residue detected in area\",\n timestamp = os.date(\"%Y-%m-%d %H:%M:%S\")\n })\n end\n \n if evidenceFound then\n -- Give evidence items to officer\n for i = 1, #evidenceTypes do\n player.Functions.AddItem('evidence_bag', 1, false, evidenceTypes[i])\n end\n \n TriggerClientEvent('QBCore:Notify', src, 'Evidence found: ' .. #evidenceTypes .. ' items collected', 'success')\n else\n TriggerClientEvent('QBCore:Notify', src, 'No evidence found in this area', 'error')\n end\nend)\n```\n\n### Market Economics System\n\n```lua\n-- Dynamic pricing based on market conditions\nfunction CalculateMarketPrice(productType, quantity)\n local basePrice = Config.Economics.base_prices[productType]\n if not basePrice then return 0 end\n \n local currentPrice = math.random(basePrice.min, basePrice.max)\n \n -- Apply demand factors\n if Config.Economics.demand_factors.time_of_day then\n local hour = tonumber(os.date(\"%H\"))\n if hour >= 20 or hour <= 6 then -- Night time\n currentPrice = currentPrice * 1.2 -- 20% premium\n end\n end\n \n if Config.Economics.demand_factors.police_presence then\n local policeCount = GetActivePoliceCount()\n if policeCount > 5 then\n currentPrice = currentPrice * 1.4 -- High risk premium\n elseif policeCount < 2 then\n currentPrice = currentPrice * 0.9 -- Low risk discount\n end\n end\n \n -- Quantity discounts for bulk sales\n if quantity > 10 then\n currentPrice = currentPrice * 0.95 -- 5% bulk discount\n elseif quantity > 50 then\n currentPrice = currentPrice * 0.90 -- 10% bulk discount\n end\n \n return math.floor(currentPrice)\nend\n\n-- Market transaction processing\nRegisterNetEvent('qb-drugs:server:sellProduct', function(productType, quantity, buyerType)\n local src = source\n local player = QBCore.Functions.GetPlayer(src)\n \n -- Check if player has the product\n local hasProduct = player.Functions.GetItemByName(productType)\n if not hasProduct or hasProduct.amount < quantity then\n TriggerClientEvent('QBCore:Notify', src, 'Insufficient product', 'error')\n return\n end\n \n -- Calculate sale price\n local unitPrice = CalculateMarketPrice(productType, quantity)\n local totalPrice = unitPrice * quantity\n \n -- Risk assessment for transaction\n local riskLevel = AssessTransactionRisk(src, productType, quantity)\n \n if riskLevel > 0.7 then -- High risk transaction\n -- Chance of police notification\n if math.random() < 0.3 then\n NotifyPolice(src, \"Suspicious activity reported\", GetEntityCoords(GetPlayerPed(src)))\n end\n end\n \n -- Process transaction\n player.Functions.RemoveItem(productType, quantity)\n player.Functions.AddMoney('cash', totalPrice, 'drug-sale')\n \n TriggerClientEvent('QBCore:Notify', src, 'Sold ' .. quantity .. 'x ' .. productType .. ' for $' .. totalPrice, 'success')\n \n -- Log transaction for investigations\n LogTransaction(player.PlayerData.citizenid, productType, quantity, totalPrice, buyerType)\nend)\n```\n\n## Troubleshooting\n\n### Common Issues\n\n#### Production Not Working\n```lua\n-- Debug production system\nRegisterCommand('debugproduction', function()\n local coords = GetEntityCoords(PlayerPedId())\n for labType, labData in pairs(Config.Labs) do\n local distance = #(coords - labData.coords)\n print(\"Lab:\", labType, \"Distance:\", distance)\n end\nend)\n```\n\n#### Market Price Issues\n- Verify price calculation factors\n- Check police count integration\n- Ensure time-based modifiers work correctly\n\n#### Investigation System Problems\n```lua\n-- Debug evidence system\nRegisterCommand('debugevidence', function()\n local evidenceCount = MySQL.scalar.await('SELECT COUNT(*) FROM drug_production_logs WHERE timestamp > DATE_SUB(NOW(), INTERVAL 24 HOUR)')\n print(\"Recent production logs:\", evidenceCount)\nend)\n```\n\n### Security Considerations\n\n1. **Anti-Exploitation**: Implement proper validation for all transactions\n2. **Audit Trails**: Log all significant drug-related activities\n3. **Balance Monitoring**: Track economic impact on server economy\n4. **Roleplay Focus**: Ensure mechanics encourage roleplay over grinding\n\n<Callout type=\"warning\">\n This system requires careful administration and clear roleplay guidelines. Monitor usage to prevent exploitation or inappropriate behavior.\n</Callout>
Last updated on