NR_DrugSelling

A street-level drug selling system with a custom React tablet UI, buyer contacts, sell zones, NPC deal outcomes, leveling, leaderboards, street chat, police dispatch integration, and full anti-exploit protection.

Features

Dependencies

Resource Description Required
ox_lib Notifications, progress bars, text UI Yes
oxmysql MySQL database for leveling, history, and chat Yes
ESX / QBCore / QBX Any supported framework (auto-detected) Yes
Inventory system ox_inventory, qb-inventory, ps-inventory, qs-inventory, and 8 more (auto-detected) Yes
ox_target / qb-target Third-eye interaction (falls back to E-key if not found) Optional
Dispatch resource ps-dispatch, cd_dispatch, qs-dispatch, rcore_dispatch, and 5 more (auto-detected) Optional
NR_Tablet Opens as a tablet app instead of standalone Optional
is_ui Alternative notification/progress bar system Optional

Supported Inventories

The script auto-detects the first running inventory from this list:

ox_inventory, qb-inventory, ps-inventory, lj-inventory,
qs-inventory, codem-inventory, ak47_qb_inventory,
ak47_esx_inventory, core_inventory, mf-inventory,
origen_inventory, tgiann-inventory, ESX built-in

Supported Dispatch Resources

ps-dispatch, cd_dispatch, qs-dispatch, core_dispatch,
rcore_dispatch, linden_outlawalert, origen_police,
emergencydispatch, op-dispatch

If no dispatch resource is detected, the script sends blip notifications directly to online LEO players as a fallback.

Installation

Step 1: Download

Download NR_DrugSelling from your Tebex purchase and extract it to your resources folder:

server/
  └── resources/
      └── [echo]/
          └── NR_DrugSelling/

Step 2: server.cfg

Add the resource to your server configuration. ox_lib and oxmysql must start before NR_DrugSelling:

ensure oxmysql
ensure ox_lib
ensure ox_target    # or qb-target (optional)
ensure NR_DrugSelling

Step 3: Inventory Items

Add the drug items to your inventory system. The default config expects these items:

Item Label Base Price
weed_bagWeed$50
coke_brickCocaine$150
meth_bagMeth$200
oxyOxy$80
crack_baggyCrack$120
heroinHeroin$250

Item names are fully configurable in Config.Drugs. Change them to match your existing drug items.

Step 4: Database

The database tables are created automatically on first start. No manual SQL setup required. Three tables are created:

Step 5: Configuration

Edit config.lua to customize drugs, contacts, sell settings, and police configuration.

Step 6: Restart

Restart your server to load the resource.

How It Works

1. Opening the App

Press F5 (default keybind) or type /drugselling in chat. If using NR_Tablet, the app opens from within the tablet interface. The dashboard shows your total earnings, drugs sold, rep level, and active contacts.

2. Checking Inventory

The Inventory tab shows which drugs you're carrying and their quantities, pulled directly from your inventory system in real time.

3. Starting a Sell

From the Sell tab, select a drug to sell. The server picks an eligible buyer contact based on your level and the drug type. A sell zone is created around the contact's location with a GPS route and radius blip.

4. Selling to NPCs

Travel to the sell zone and approach any NPC pedestrian within the radius. Use ox_target / qb-target (or press E) to initiate a deal. A handoff animation plays with a progress bar.

5. Deal Outcomes

Each NPC interaction rolls a random outcome:

Outcome Default Chance What Happens
Buy 35% NPC buys a random quantity at the contact's price multiplier. You get cash and XP.
Rob 35% NPC takes your drugs and runs. Kill them and search the body to recover items.
Attack 15% An armed NPC spawns nearby and attacks you.
Dispatch 15% NPC calls the cops. Police are alerted via dispatch.
Ignore Remaining % NPC isn't interested. Try another one.

6. Sell Zone Timer

The sell zone stays active for a configurable duration (default 15 minutes). You can sell to multiple NPCs during this window. When the timer expires, the zone closes and a cooldown begins before you can sell again.

7. Leveling Up

You earn 1 XP per unit sold. Leveling up unlocks new buyer contacts with better price multipliers and increases your max sell quantity per deal. The Rank tab shows your progression and upcoming unlocks.

8. Street Chat

The in-app chat lets players communicate with aliases. Set your alias from the dashboard, toggle anonymous mode, and chat with other drug sellers server-wide. Messages persist in the database.

9. Leaderboard

The leaderboard ranks all players by total drugs sold, displayed with their chosen aliases. It updates in real time as sales are completed.

Configuration

General Settings

Config.Debug = false          -- Enable debug mode
Config.Theme = '#00ffff'      -- UI accent color
Config.UsingNRTablet = true   -- Open as NR_Tablet app
Config.Keybind = 'F5'         -- Open keybind (standalone mode)

Leveling

Config.MaxLevel = 25          -- Maximum player level
Config.XPPerLevel = 100       -- XP needed per level

Drug Definitions

Config.Drugs = {
    { item = 'weed_bag',    label = 'Weed',    basePrice = 50,  icon = 'leaf' },
    { item = 'coke_brick',  label = 'Cocaine',  basePrice = 150, icon = 'snowflake' },
    { item = 'meth_bag',    label = 'Meth',     basePrice = 200, icon = 'flask' },
    { item = 'oxy',         label = 'Oxy',      basePrice = 80,  icon = 'pills' },
    { item = 'crack_baggy', label = 'Crack',    basePrice = 120, icon = 'fire' },
    { item = 'heroin',      label = 'Heroin',   basePrice = 250, icon = 'syringe' },
}

Add or remove entries to match your server's drug items. Icons use FontAwesome names.

Buyer Contacts

{
    id = 1,
    name = 'Street Corner Kid',      -- Display name
    location = 'Grove Street',        -- Location label
    coords = vec3(-182.47, -1676.87, 33.84),
    drugs = { 'weed_bag', 'crack_baggy' },  -- Accepted drugs
    multiplier = 0.8,                 -- Price multiplier
    risk = 'Low',                     -- Risk label
    unlockLevel = 1,                  -- Required level
}

Higher-level contacts have better multipliers but may be in more dangerous locations. The default config includes 7 contacts from level 1 to level 20.

Contact Multipliers

Contact Multiplier Unlock Level Risk
Street Corner Kid0.8x1Low
The Plug1.0x3Medium
Backstreet Doc1.1x5Medium
Cartel Contact1.3x8High
Club Owner1.2x10Medium
Biker Gang1.5x15High
Kingpin1.8x20High

Sell Settings

Config.BaseSellMax = 5         -- Max units at level 1
Config.SellMaxPerLevel = 2    -- +2 per level above 1
Config.SellCooldown = 900     -- Seconds cooldown after zone expires
Config.SellZoneRadius = 200.0 -- Radius of the sell zone
Config.SellZoneTimeout = 900  -- Seconds the sell zone is active

Max sell quantity formula: BaseSellMax + SellMaxPerLevel * (level - 1). At level 25, players can sell up to 53 units per NPC interaction.

Deal Outcome Chances

Config.BuyChance = 0.35       -- 35% NPC buys
Config.RobChance = 0.35      -- 35% NPC robs you
Config.AttackChance = 0.15   -- 15% armed NPC attacks
Config.DispatchChance = 0.15 -- 15% NPC calls police

Any remaining probability (if total < 1.0) becomes the ignore chance.

Attack NPC Settings

Config.AttackSpawnDistance = 15.0  -- Min spawn distance
Config.AttackDespawnTime = 120    -- Seconds before cleanup
Config.AttackWeapons = {
    'WEAPON_PISTOL', 'WEAPON_SWITCHBLADE',
    'WEAPON_KNIFE', 'WEAPON_BAT', 'WEAPON_BOTTLE',
}

Police Settings

Config.RequiredPolice = 0      -- Min LEO online (0 = disabled)
Config.LeoJobs = { 'police', 'sheriff', 'bcso', 'sasp', 'ranger' }

-- Police alert to seller (warning notification)
Config.PoliceAlertChance = 0.10
Config.PoliceAlertChancePerLevel = 0.01
Config.PoliceAlertChanceMax = 0.40

-- Police dispatch (blip/alert to LEO players)
Config.PoliceNotifyChance = 0.25
Config.PoliceNotifyChancePerLevel = 0.015
Config.PoliceNotifyChanceMax = 0.60

Both police chances scale with player level: base + perLevel * (level - 1), capped at max. Higher-level dealers attract more police attention.

NPC Interaction

Config.InteractDistance = 2.0  -- How close to interact
Config.DealDuration = 5000    -- Progress bar duration (ms)

Pricing System

The final sale price per unit is calculated as:

price = basePrice * contactMultiplier * randomVariance

Where randomVariance is between 0.7 and 1.4 (30% below to 40% above base). This means prices fluctuate per deal, adding unpredictability.

Database

NR_DrugSelling uses oxmysql with three auto-created tables:

nr_drugselling (Player Profiles)

ColumnTypeDescription
citizenidVARCHAR(50)Unique player identifier
aliasVARCHAR(50)Player's chosen street name
levelINTCurrent level (1-25)
xpINTCurrent XP towards next level
total_earnedINTLifetime cash earned
total_soldINTLifetime units sold
chat_anonymousTINYINTAnonymous chat preference

nr_drugselling_history (Transaction Log)

ColumnTypeDescription
citizenidVARCHAR(50)Seller identifier
drugVARCHAR(50)Item name sold
quantityINTUnits sold
price_per_unitINTPrice per unit at time of sale
total_priceINTTotal cash received
buyerVARCHAR(100)Contact name
sold_atTIMESTAMPSale timestamp

nr_drugselling_chat (Street Chat)

ColumnTypeDescription
citizenidVARCHAR(50)Sender identifier
aliasVARCHAR(50)Display name (or "Anonymous")
messageVARCHAR(500)Message content
sent_atTIMESTAMPMessage timestamp

Localization

All UI text is configurable in locales.lua. Override any string to change labels, notifications, and tab names. Example:

Locales.AppTitle = 'Drug Selling Hub'
Locales.TabDashboard = 'Dashboard'
Locales.TabInventory = 'Inventory'
Locales.FindBuyer = 'Find Buyer'
Locales.SellSuccess = 'Deal complete'
Locales.PoliceAlert = 'The cops have been tipped off!'

Troubleshooting

UI not opening

No buyers available

Sell zone not appearing

Can't interact with NPCs in zone

Database errors

Items not being removed/added

Support

For paid script support, open a ticket in our Discord server for priority assistance.