X3D Sell Drug
Shady buyers appear around the map on a timer and pay in black money. Runs on ESX or standalone.
Buy / Get freeConfig builderInstallation
- Drop the
x3d_selldrugfolder intoresources/ - Add it to
server.cfg:
ensure x3d_selldrug
That is all. No SQL.
Configuration
Everything lives in shared/config.lua.
-- framework: 'auto' uses ESX when es_extended is there, otherwise standalone · 'esx' · 'standalone'
Config.Framework = 'auto'
Config.Locale = 'th' -- language of the text
Config.InteractDistance = 2.5 -- how close you must be to press E
Config.StreamDistance = 60.0 -- how close before the ped spawns
Buyer groups (Config.Groups)
Each group has its own items, prices, spots and blip. Two come by default: street (shady buyers) and event (big buyer).
| Option | What it does |
|---|---|
activeCount |
buyers live at once (0 = not standing around, driven by schedule) |
lifeTime / respawnDelay |
how long each buyer stays (seconds) / delay before a new one (ms), { min, max } |
exclusive |
true = one seller per buyer at a time · false = everyone may sell once |
blockedJobs |
jobs that cannot sell, e.g. { police = true } |
progressMs |
sale duration in ms |
minigame |
{ enabled, rounds, difficulty } ox_lib skill check before the sale (skipped without ox_lib) |
models / scenarios |
ped looks and idle animations |
blip |
sprite scale name colour · flash blinks · shortRange = false = visible map-wide |
offers |
what they buy and the pay: { items = { { name, count } }, pay = { min, max } } |
spots |
where buyers appear: vector4(x, y, z, heading), add or remove as you like |
spotsFrom / offersFrom |
reuse another group's spots or price table, e.g. 'street' |
Jobs and alerts
-- minimum on-duty players per job before anyone can sell ({} = no check)
Config.RequiredJobs = { police = 2 }
-- alert these jobs after a sale, with `chance` per sale (jobs = {} = off)
Config.Alert = { jobs = { 'police' }, chance = 0.3, delay = 10000, blipTime = 60 }
-- jobs that cannot sell, per group
Config.Groups.street.blockedJobs = { police = true }
- Only on-duty players count (ESX
job.onDuty). The server checks when a sale starts - Standalone has no jobs: if you set
RequiredJobs, fillFramework.GetJobinaddons/framework/server.lua
Big-buyer events
The event block in Config.Groups (delete the whole block = no events):
event = {
schedule = { every = { min = 1800, max = 3600 }, count = 1, announce = true }, -- every 30–60 min, tell everyone
lifeTime = { min = 900, max = 1200 }, -- stays 15–20 min
spotsFrom = 'street', -- picks from the normal spots
offersFrom = 'street', -- items and prices from the normal table
quantity = 10, -- 10 units per deal, must carry all of them
payMultiplier = 1.2, -- normal price × 10 × 1.2
progressMs = 180000, -- each sale takes 3 minutes (can be cancelled)
blip = { flash = true, shortRange = false, colour = 5,
ring = { radius = 60.0, colour = 5, alpha = 110 }, pulse = 4000 }, -- flashing, visible map-wide
}
- Everyone may sell once per event · a buyer with a sale in progress waits until it finishes before leaving
- Admins can press "Start an event now" in x3d_adminpanel, or call
exports.x3d_selldrug:StartEvent('event') - Normal groups accept
blip.flash = truetoo (off by default)
Editing spots from the X3D admin panel
x3d_adminpanel menu "Shady deals › Buyer spots": add a spot where you stand · teleport · enable/disable · move the buyer · hold to delete.
Spots live in the script's KVP (selldrug:spots), not the config: editing Config.Groups[...].spots after the first start has no effect, use the panel instead.
Own admin panel? Call SpotAdmin.addHere / toggle / remove / moveBuyer / teleport server-side, or the net events x3d_selldrug:adminAddHere / adminToggle / adminRemove / adminRespawn (admin check built in).
Admin blips
Admins see every buyer spot, empty ones too (green = buyer there · faded = empty · faded red = disabled) as map blips; players never do, the server sends the coordinates to admins only.
- Without the X3D admin panel: set
Config.AdminBlips = trueand admins get them on join (ESXadmin/superadminor ACE<resource name>.admin) - With x3d_adminpanel: this script's menu in the panel lists every spot and has a toggle button that only affects whoever presses it
Hooking other systems after a sale
addons/hooks/server.lua → Hooks.OnSold(src, sale) runs after the dirty money is paid (sale = { group, pay, items }). Use it for XP, quests or logs.
Hooks.OnEventBuyer(buyer) / Hooks.OnEventBuyerGone(uid) run when an event buyer appears and leaves (buyer = { uid, group, label, labelEn, coords, endsAt }). By default they feed X3D Map Events when it is on the server (pause-menu event panel + click to navigate); without it they do nothing.
Items
Whatever they buy has to already exist in your items table. This script does not add items.
The negotiation minigame (optional)
With ox_lib started, a skill check runs before the sale and failing it fails the deal. Without ox_lib the step is skipped and the sale works normally — the real security is the server's item/distance/timing re-check at the end of the deal, not the minigame.
Laundering
Payouts go through Framework.AddMoney, paid as black_money — a normal ESX account in ESX mode, or, in standalone (no es_extended), an ox_inventory item named black_money (make sure that item exists in your items table).
Troubleshooting
No buyers anywhere — check the group has spots and its activeCount is not 0.
E does nothing — stand closer than Config.InteractDistance, and not in a vehicle.
Sold but no money — check the server console; usually not enough items, or the player left the radius mid-deal.