Configuration
Every drug sales option in config.lua, strings.lua and logs.lua with its default, plus the prompt setting in client/functions.lua.
drug sales is set up in three files at the root of the resource, all shipped open: config.lua (the Config table), strings.lua (every line players read) and logs.lua (logging, read by the server only). The prompt system is a line in client/functions.lua. Changes apply when the resource starts again.
The sections below follow config.lua from the top.
Setup
| Option | Default | What it does |
|---|---|---|
Config.Setup.debug | false | Draws every zone's sphere in the world. Keep it off on a live server. |
Config.Setup.target | 'none' | 'none' shows the E prompt by the nearest local. 'ox_target', 'qb-target' or 'qtarget' puts Sell drugs on locals instead. With lation interact running, pick any of the three: it answers to all of them. 'custom' does nothing until you fill in the target functions in client/functions.lua. |
Config.Setup.notify | 'ox_lib' | Also 'lation_ui', 'esx', 'qb', 'okok' (okokNotify), 'sd-notify', 'wasabi_notify' or 'custom'. Notifications are titled "Drugs". |
Config.Setup.menu | 'ox_lib' | Also 'lation_ui' or 'custom'. The selling menu and Your Statistics. |
Config.Setup.dispatch | 'custom' | Where police alerts go. See dispatch. |
Config.Setup.versionCheck | true | Checks for a newer release on start and prints a notice in the server console. |
Config.Setup.interactKey | 38 | The control for the selling prompt and for claiming robbed drugs, when there's no target system. 38 is E. The prompts say E in strings.lua, so change Strings.TextUI to match. |
Config.Setup.requestWait | 10000 | Milliseconds to wait for an animation or prop to load. |
Config.Setup.blacklistJobs | { 'police', 'ambulance' } | Jobs that can't sell. Checked when the player enters a zone. |
Config.Setup.dymanic | true | Spelled this way. The prompt only turns on while the player carries a drug the zone buys at their level. With it off, the prompt shows to everyone in the zone. |
Config.Setup.excludeScriptPeds | true | Only locals the game spawned can buy. With it off, peds spawned by other scripts can too, as long as they're networked. |
The custom options are empty branches in client/functions.lua, which ships open. See developers.
Dispatch
Config.Setup.dispatch takes cd_dispatch, ps-dispatch, qs-dispatch, core_dispatch, rcore_dispatch, aty_dispatch, op-dispatch, origen_police, emergencydispatch or custom. An alert is sent when a buyer turns a player down and when a bystander reports a sale.
Most alerts read 10-420 | Drug Sale with "A citizen has reported a potential drug sale on" and the street; core_dispatch gets 10-911, "Potential Drug Sale". cd_dispatch, qs-dispatch, rcore_dispatch, aty_dispatch and emergencydispatch alert the jobs in Config.Police.jobs; core_dispatch, op-dispatch and origen_police alert police. The text of each is in PoliceDispatch in client/functions.lua.
custom, the default, sends nothing. To use another dispatch, write its call in PoliceDispatch in client/functions.lua, under the custom branch:
elseif Config.Setup.dispatch == 'custom' then
-- data.coords: where the seller stands, data.street: the street name
exports['my-dispatch']:SendAlert({
code = '10-420',
title = 'Drug Sale',
coords = data.coords,
street = data.street,
jobs = Config.Police.jobs,
})
end(my-dispatch and its SendAlert stand for your dispatch's own export.)
Police
| Option | Default | What it does |
|---|---|---|
Config.Police.jobs | { 'police', 'sheriff' } | Jobs counted as police, for police risk and for zones that need police on duty. On Qbox and QBCore only players on duty count. |
Config.Police.risk | true | Prices rise with the police on duty, and the menu shows the Risk bonus line. |
Config.Police.percent | 5 | Percent added to the price for each officer on duty. With 3 on, prices are 15% higher. |
Reputation
Config.Reputation = {
levelUp = 25000,
levels = {
[1] = { description = 'Being new to dealing can be tough', priceBoost = 0, reduceReject = 0, reduceRobbery = 0 },
[2] = { description = 'You\'re getting some loyal clients', priceBoost = 5, reduceReject = 10, reduceRobbery = 0 },
-- levels 3 to 5 as in the table on the selling page
}
}| Option | Default | What it does |
|---|---|---|
levelUp | 25000 | Reputation to go up one level. Each level starts again from 0, and any excess carries over. |
levels | Five levels | Add or remove levels, numbered in order from 1. The last one is the top. |
description | The line under Reputation | Level N in the menu | |
priceBoost | 0 (level 1) to 40 (level 5) | Percent added to the price, on top of police risk |
reduceReject | 0 (level 1) to 40 (level 5) | Percent taken off each drug's refusal chance (callChance). 40 turns 20% into 12%. |
reduceRobbery | 0 (levels 1 and 2) to 30 (level 5) | Percent taken off the zone's robbery chance |
The defaults for every level are on the selling page. XP per sale is set per zone, in addXP.
Animations
| Option | Default | What it does |
|---|---|---|
Config.Animations.accepted | mp_common / givetake1_a, cash prop hei_prop_heist_cash_pile | The hand-off, played by the seller and the buyer. The seller starts with the drug's own object and the buyer with the cash, and they swap. It takes 3 seconds. |
Config.Animations.rejected | cellphone@ / cellphone_call_listen_base, prop_npc_phone_02, duration = 5000 | The buyer's phone call after a refusal |
Config.Animations.claimItems | pickup_object / pickup_low, duration = 1500 | The seller picking robbed drugs back up |
Each has dict and clip. A prop has model, pos and rot (vectors, relative to the hand), and duration is in milliseconds.
Purity pricing
Config.Metadata lists the items priced by a number in their metadata instead of a zone's price range. Any item from any script can be listed.
Config.Metadata = {
['ls_cocaine_bag'] = { key = 'purity', price_per_purity = 2.5, perfect_bonus = 100 },
['ls_meth'] = { key = 'purity', price_per_purity = 2.5, perfect_bonus = 100 },
-- ...
}| Option | Default | What it does |
|---|---|---|
key | 'purity' | The metadata field to read |
price_per_purity | 2.5 | Dollars for each point. 50 purity is $125. |
perfect_bonus | 100 | Added at 100 or more. 100 purity is $350. 0 turns it off. |
Listed by default: ls_cocaine_bag and ls_crack_bag (coke processing), ls_meth (meth crafting) and the six lation weed bags: ls_og_kush_bag, ls_banana_kush_bag, ls_blue_dream_bag, ls_purple_haze_bag, ls_orange_crush_bag and ls_cosmic_kush_bag.
The value is read from the first stack of that item the player carries. A listed item with no value sells for $2 (a value of 1) and F8 prints a warning. Remove an item from the table to price it by its zone's price range again.
Zones
Config.Zones is a numbered list of zones. Add, move or remove them freely; the six defaults are described on the selling page.
Config.Zones = {
[1] = {
name = 'Vinewood',
coords = vec3(284.3999, -86.8160, 70.1332),
size = 500,
settings = { ... },
drugs = { ... },
blip = { ... },
ignoreModels = { 's_f_y_cop_01', 's_m_y_cop_01' },
},
}| Option | What it is |
|---|---|
name | The zone's name, for your own reference |
coords | Its centre |
size | Its radius in meters |
Settings
Config.Zones[n].settings, with Vinewood's values:
| Option | Default | What it does |
|---|---|---|
addXP | { min = 5, max = 15 } | Reputation each sale gives, picked at random in the range |
level | 1 | The level a player needs before the zone works for them |
daytime | true | true sells at any hour. false sells only at night, 21:00 to 05:59 in game. |
money | 'black_money' | What a sale pays. See money. |
metadata | true | QBCore only: pay markedbills, cashrolls or bands as one item holding the worth |
requirePolice | false | Refuse to sell until enough police are on duty |
count | 1 | How many, when requirePolice is on |
enableRobbery | true | Buyers can rob the seller |
chance | 5 | Robbery chance in percent, before the level's cut |
anonymousCalls | true | A bystander can report a sale that went through, without the seller knowing |
callChance | 10 | Bystander report chance in percent, for every sale in the zone |
cooldown | false | Make the player wait after each sale |
duration | 15000 | The cooldown in milliseconds |
limit | false | Cap how many drugs each player can sell here until the server restarts |
cap | 100 | The cap, counted in drugs sold |
Money
What money does depends on your framework:
Always given as an inventory item, so black_money works, and so does money for cash in ox_inventory. bank and cash don't.
cashorbankgo to that account.markedbills,cashrollsorbandswithmetadata = trueare one item whoseworthis the sale. A player who already has one gets a single item with both worths added up. Withmetadata = false, the player gets one item per dollar.- Anything else, the default
black_moneyincluded, is given as that many of an item, so it has to exist in your items.
black_money, money or bank go to that account. Anything else is given as that many of an item.
Drugs
Config.Zones[n].drugs lists the items a zone buys, keyed by item name. Every default zone lists the same nine; see the drugs.
drugs = {
['ls_og_kush_bag'] = {
label = 'OG Kush Weed',
icon = 'fas fa-cannabis',
level = 1,
callChance = 5,
price = { min = 50, max = 100 },
quantity = { min = 1, max = 1 },
object = {
model = 'prop_weed_bottle',
position = vec3(0.13, 0.02, 0.0),
rotation = vec3(-90.0, 0.0, 0.0)
},
},
}| Option | What it does |
|---|---|
label | The drug's name in the menu |
icon | A Font Awesome icon for the menu |
iconColor | Optional. The icon's color. |
level | The level a player needs to see it in this zone |
callChance | Chance in percent that the buyer turns the player down and calls the police, before the level's cut. 5 to 20 by default. |
price | The price range for one. Not used while the item is in Config.Metadata, which is why the meth, cocaine and crack entries are 0. |
quantity | How many a buyer takes, picked at random in the range and never more than the player has. A player with fewer than min doesn't see the drug. |
object | The prop in the seller's hand during the hand-off: model, position and rotation |
To sell another item, add an entry with its item name to every zone that should buy it.
Blip
| Option | Default | What it does |
|---|---|---|
enabled | true | Show the zone on the map |
radius | true | Shade the zone's whole area |
sprite | 51 | The blip icon |
color | 1 | The blip and area color (red) |
scale | 0.8 | The blip's size |
label | 'Drug Selling Zone' | The name on the map |
Ignored models
ignoreModels lists ped models that won't buy in that zone. A player who tries one sees "The buyer completely ignores you". The defaults are the two police models, s_f_y_cop_01 and s_m_y_cop_01.
Prompt system
The selling and claim prompts go through a line at the top of client/functions.lua:
| Option | Default | What it does |
|---|---|---|
textui | 'ox_lib' | Also 'lation_ui', 'jg-textui', 'okokTextUI', 'qbcore' or 'custom'. Only used while Config.Setup.target is 'none'. |
Text
strings.lua holds every line players read, in English, in the Strings table:
| Table | What's in it |
|---|---|
Strings.Symbols | $, x, each and +, as the menu builds prices |
Strings.Notify | rejects (the 17 refusal lines, add or remove freely), robbed, escaped, daytime, police, ignoreModel, cooldown, limit, levelUp and noVehicle |
Strings.TextUI | The two prompts: selling (Sell Drugs, E - Open Menu) and robbed (Claim Drugs, E - Take Back), each with an icon |
Strings.Target | The two target options, selling (Sell drugs) and robbed (Take drugs): label, icon, color and dist (3.0 m) |
Strings.Menu | The menu: titles, descriptions, the price card's lines, icons and icon colors |
Strings.Logs | Each log's title and message |
Logs
logs.lua is loaded by the server only, so a webhook in it never reaches players.
| Option | Default | What it does |
|---|---|---|
Logs.Service | 'discord' | 'fivemanage', 'fivemerr', 'discord' or 'none'. Fivemanage needs fmsdk and Fivemerr needs fm-logs, started before lation_selling. |
Logs.Screenshots | false | Attach a screenshot of the player's screen. Fivemanage and Fivemerr only. |
Logs.Events.selling | false | Each completed sale: who, how many of what, and for how much |
Logs.Events.robbed | false | Each robbery, with what was taken |
Logs.Events.claimed | false | Each time a player takes robbed drugs back |
Logs.Events.leveled | false | Each level up |
Logs.Discord.name | 'Drug Selling Logs' | The webhook's name |
Logs.Discord.link | '' | The webhook URL |
Logs.Discord.image | An image link | The webhook's picture |
Logs.Discord.footer | An image link | The icon in each message's footer, beside the date |
Every event is off by default, so nothing is logged until you turn one on.
Still stuck? Ask in our Discord: the people who write the scripts answer.
Last updated
Selling
How a sale works in drug sales with the default settings, from the zones and finding a buyer to the menu, refusals, robberies, prices and reputation levels.
Developers
The drug sales server and client exports, its notification event and state bag, and the open functions for prices, payouts, police counts, dispatch and sale checks.