Configuration
Every coke processing option in config/shared.lua, config/client.lua, config/server.lua and config/icons.lua with its default, plus the text UI and language files.
coke processing is set in four files in config/. Each returns one table, and the options below are written as paths inside it (setup.notify, settings.limit). The files ship open, along with locales/, the bridge and the two functions.lua files. Restart the server after a change.
config/shared.lua: the field, plants, tables, cement, the shops, labs, raids, cooking and consumables.config/client.lua: placement and camera controls, lifetime stats and every progress bar.config/server.lua: logging.config/icons.lua: icons and colors.
config/shared.lua
Setup
| Option | Default | What it does |
|---|---|---|
setup.debug | false | Draws the zones, prints the soil hash under a plant being placed in F8, draws the table's collision rays, and adds /getrot and /getbucket. It costs resource time, so keep it off in production. |
setup.interact | 'ox_target' | 'ox_target', 'qb-target', 'interact' or 'custom'. Keep 'ox_target' with lation interact. 'custom' does nothing until you add your calls in client/functions.lua. |
setup.notify | 'ox_lib' | 'lation_ui', 'ox_lib', 'esx', 'qb', 'okok', 'sd-notify', 'wasabi_notify' or 'custom' |
setup.progress | 'ox_lib' | 'lation_ui', 'ox_lib', 'qbcore' or 'custom'. A custom progress bar has to play the animations. |
setup.minigame | 'ox_lib' | The raid skill checks: 'lation_ui', 'ox_lib' or 'custom' |
setup.menu | 'ox_lib' | 'lation_ui', 'ox_lib' or 'custom' |
setup.dialogs | 'ox_lib' | Confirmations and input dialogs: 'lation_ui', 'ox_lib' or 'custom' |
setup.version | true | Prints a line in the server console when an update is out |
setup.request | 10000 | Milliseconds to wait for a model or animation to load |
setup.render | 100 | Meters within which plants, tables and the farmer appear |
setup.police | { 'police', 'sheriff' } | The police jobs. They count toward police requirements, can raid and confiscate, can destroy plants when planting.anyone_destroy is off, and get the alerts in dispatch scripts that take a job list. On Qbox and QBCore only players on duty count. |
The coca field
| Option | Default | What it does |
|---|---|---|
cooldown | 180 | Seconds a searched wild plant stays empty, for everyone |
limit | 100 | Leaves each player can search until the script restarts |
farms is a list of fields. The first one ships set up near Grapeseed:
farms = {
[1] = {
spawn = true,
model = 'coca_growth_3_wild',
center = vec3(2139.1252, 5169.0010, 54.1451),
size = 150,
level = 1,
required = {
{ item = 'ls_shears', quantity = 1, remove = false },
},
reward = { item = 'ls_coca_leaf', quantity = { min = 1, max = 1 } },
seed = { item = 'ls_coca_seed', quantity = { min = 1, max = 1 }, chance = 5 },
xp = { min = 1, max = 1 },
blip = { enable = true, sprite = 89, color = 1, scale = 0.7, label = 'Coca Field' },
coca = {
[1] = vec3(2179.3621, 5155.1704, 53.9840),
-- 49 plants in all
}
},
},| Field | What it does |
|---|---|
spawn | true spawns model at each point. false puts the prompt on whatever already stands there. |
model | The prop to spawn. coke processing streams coca_growth_1_wild, coca_growth_2_wild and coca_growth_3_wild. |
center | The middle of the field. Props appear when a player comes within size of it. |
size | The field's radius in meters. A search more than 5 m outside it is refused. |
level | The level needed to search here |
required | Items a player must carry to search. They are never taken. |
reward | The item each search gives, and how many |
seed | A second item, given chance percent of the time |
xp | XP for each item from reward |
blip | The map blip at center |
coca | The plants: a prop spawns at each point when spawn is on, and the Search prompt sits there |
Planting
| Option | Default | What it does |
|---|---|---|
planting.seed | 'ls_coca_seed' | The usable item that plants a coca plant |
planting.max | 5 | Plants each player can own at once |
planting.anyone_destroy | true | true lets anyone destroy a plant. false keeps it to the owner and police. |
planting.collision | true | Refuses a spot inside an object |
planting.required | Plant Pot x1, remove = true | Items needed to plant. remove = true takes them when the plant goes down. |
planting.police | 0 | Police needed online to plant |
planting.soil.enable | true | Plants only go down on the soil types in soil.types |
planting.soil.types | 17 soil hashes | The allowed ground. With setup.debug on, placing a plant prints the hash under it in F8. |
planting.soil.ignore | A placeholder at 0, 0, 0 | Areas (coords, radius) where any ground is allowed, such as a warehouse floor |
planting.blacklist | A placeholder at 0, 0, 0 | Areas (coords, radius) where players can't plant |
planting.restrict.enable | false | Players can only plant inside restrict.whitelist |
planting.restrict.whitelist | A placeholder at 0, 0, 0 | Areas (coords, radius) where planting is allowed while restrict.enable is on |
planting.stages | coca_growth_1, coca_growth_2, coca_growth_3 | The prop for each growth stage |
Growth
| Option | Default | What it does |
|---|---|---|
growth.update_interval | 15000 | About how often each plant updates, in milliseconds |
growth.starting | thirst = 85, hunger = 85, yield = 100, growth = 0 | A new plant's water, fertilizer, yield and growth, in percent |
growth.growth_increase | min = 0.15, max = 0.35 | Growth added each update |
growth.stages | [2] = 40, [3] = 90 | The growth at which a plant moves to stage 2 and stage 3 |
growth.watering | item = 'ls_watering_can', min = 8.0, max = 13.0 | The watering item, and the water one use adds |
growth.fertilizing | item = 'ls_fertilizer', min = 10.0, max = 15.0 | The fertilizer item, and how much one use adds |
growth.thirst | min = 0.12, max = 0.3 | Water lost each update |
growth.hunger | min = 0.11, max = 0.3 | Fertilizer lost each update |
growth.death | 20 | A plant dies when its water or fertilizer falls to this |
growth.yield_threshold | 70 | Below this water or fertilizer, yield falls each update |
growth.yield_decrease | min = 0.4, max = 0.9 | Yield lost each update below the threshold |
Harvest
| Option | Default | What it does |
|---|---|---|
harvest.required | Shears x1, remove = false | Items needed to harvest |
harvest.add.leaf | 'ls_coca_leaf' | The item a harvest gives |
harvest.add.yield_per_10_percent | 3 | Leaves for every 10% of yield: 30 at 100%, 15 at 50% |
harvest.add.seed | 1 ls_coca_seed, required_yield = 95 | The seed given back, only at a yield of required_yield or more |
harvest.add.xp | min = 1, max = 1 | XP for each leaf, to the plant's owner |
Tables
| Option | Default | What it does |
|---|---|---|
table.item | 'ls_coke_table' | The usable item that places a table |
table.model | 'bkr_prop_coke_table01a' | The table prop |
table.locked | false | true keeps each table to the player who placed it: only they see it as usable and can pack it up |
table.limit | 1 | Tables each player can have out |
table.collisions | true | Turns the outline red while the table touches an object. A table is refused there either way. |
table.police.place | 0 | Police needed online to place a table |
table.police.use | 0 | Police needed online to open a table |
table.restricted | A placeholder at 0, 0, 0 | Areas (coords, radius) where tables can't be placed |
Experience
experience = {
[1] = 0,
[2] = 2500,
[3] = 10000,
[4] = 20000,
[5] = 50000,
[6] = 100000,
},The XP each level needs. Level 1 must be 0. Add or remove levels as you like, numbered in order.
Cement
| Option | Default | What it does |
|---|---|---|
cement.enable | true | Turns cement collecting on |
cement.limit | 25 | Bags each player can take until the script restarts |
cement.cooldown | 180 | Seconds a pallet stays empty after a take, for everyone |
cement.dispatch | chance = 5, sprite = 133, color = 1, scale = 1.0 | The chance, in percent, that a take alerts police, and the alert's blip |
cement.zones | One construction site | Each zone has points and thickness (a polygon; ox_lib's /zone command can build one), reward (1 ls_cement), xp (0) and coords, the 36 pallets that get the Take cement prompt |
Nothing is spawned for cement: point coords at objects already in the world. Each bag comes with 100 durability.
Supply shop
| Option | Default | What it does |
|---|---|---|
shop.enable | true | Spawns the farmer |
shop.location | vec4(1901.1145, 4924.4526, 48.8241, 207.5563) | Where the farmer stands, and which way they face |
shop.model | 'a_m_m_farmer_01' | The ped |
shop.scenario | 'WORLD_HUMAN_DRINKING' | What the ped does; nil or false for nothing |
shop.hours | min = 0, max = 24 | In-game hours the farmer is there. A min above max runs past midnight, such as 21 to 5. |
shop.account | 'cash' | 'cash' or 'bank' |
shop.items | Eight items | Each with item, price, icon and, for the items that need it, metadata: the durability it comes with |
shop.blip | enable = true, sprite = 280, color = 0, scale = 0.9, label = 'Farmer' | The farmer's blip. It shows whenever blip.enable is on, even with the shop off. |
items = {
[1] = { item = 'ls_watering_can', price = 15, icon = 'droplet', metadata = 100 },
[2] = { item = 'ls_fertilizer', price = 20, icon = 'burger', metadata = 100 },
[3] = { item = 'ls_plant_pot', price = 10, icon = 'plant-wilt' },
[4] = { item = 'ls_shears', price = 150, icon = 'scissors' },
[5] = { item = 'ls_baking_soda', price = 15, icon = 'box-archive' },
[6] = { item = 'ls_empty_baggy', price = 5, icon = 'bag-shopping' },
[7] = { item = 'ls_gasoline', price = 50, icon = 'gas-pump', metadata = 100 },
[8] = { item = 'ls_coke_table', price = 5000, icon = 'snowflake' },
},Labs
labs is a list of labs for sale. Five ship; see buying a lab for their prices and stashes.
labs = {
[1] = {
enter = vec4(499.6197, -651.9501, 24.9085, 262.6456),
description = 'A modest lab located in Textile City on Little Bighorn',
image = 'nui://lation_coke/labs/lab1.jpg',
icon = 'fas fa-warehouse',
price = 100000,
level = 1,
camrot = vec3(-0.000001, -0.000000, -97.354431),
storage = {
[1] = {
identifier = 'lab1_stash1',
label = 'Storage',
coords = vec3(1096.9021, -3192.4685, -38.8690),
slots = 50,
weight = 50000
},
}
},
},| Field | What it does |
|---|---|
enter | The door: where Enter sits, and where players come out |
description | The line under the price in Lab Availability |
image | The picture in Lab Availability; nil for none |
icon | The icon in Lab Availability |
price | What the lab costs |
level | The level needed to buy it, or to be handed it by transfer |
camrot | The rotation of View Camera. Stand at the door facing away from it, turn on setup.debug and run /getrot. |
storage | The stashes inside: identifier (unique across every lab), label, coords, slots and weight |
Lab settings
| Option | Default | What it does |
|---|---|---|
settings.accounts | purchase = 'cash', upgrade = 'cash', sell = 'cash' | Where buying and upgrading are paid from and the sale is paid into: 'cash' or 'bank' |
settings.enter | vec4(1088.7609, -3187.5291, -38.9934, 181.0739) | Where players arrive inside |
settings.exit | vec4(1088.7609, -3187.5291, -38.9934, 181.0739) | Where Exit sits inside |
settings.manage | vec3(1086.5208, -3194.2824, -39.1940) | The laptop, with Manage lab and Confiscate equipment |
settings.stations.basic | 3 positions | The stations before the equipment upgrade |
settings.stations.upgrade | 5 positions | The stations after it |
settings.limit | 1 | Labs each player can own |
settings.defaults | style = 'basic', security = 'basic' | A new lab's equipment and security, 'basic' or 'upgrade' |
settings.permissions | manageDoor = false, viewCamera = false, manageUsers = false | What a newly added authorized user can do |
settings.upgrades.style | price = 15000, duration = 60 | Upgrade Equipment: the price and the minutes it takes |
settings.upgrades.security | price = 10000, duration = 30 | Install Security: the price and the minutes it takes |
settings.selling.confirm | 'confirm' | The word an owner types to sell |
settings.selling.refund | 50 | Percent of the lab's price paid back on a sale |
settings.inactivity.enable | true | Releases labs nobody uses |
settings.inactivity.threshold_days | 30 | Days without activity before a lab is released |
settings.inactivity.check_interval_minutes | 15 | How often the server looks for inactive labs |
settings.inactivity.force_eject | true | Puts out anyone still inside 10 seconds after a release |
settings.blip | name = 'Coke Lab', sprite = 473, color = 0, scale = 0.8 | The owner's blip on their lab |
Raids
| Option | Default | What it does |
|---|---|---|
raids.police | true | Police can break into locked labs and passcoded stashes |
raids.players | true | Everyone else can too |
raids.skillcheck.entry | difficulty = { 'easy', 'easy', 'easy', 'medium', 'medium', 'medium', 'hard' }, inputs = { 'W', 'A', 'S', 'D' } | The skill check at a locked door |
raids.skillcheck.stash | The same | The skill check at a passcoded stash |
Lab dealer
| Option | Default | What it does |
|---|---|---|
dealer.enable | true | Spawns the lab dealer. With it off, the openLabShop export still opens the menu. |
dealer.location | vec4(-7.2472, 409.2823, 120.1271, 76.4763) | Where the dealer stands |
dealer.model | 'a_m_m_eastsa_02' | The ped |
dealer.scenario | 'WORLD_HUMAN_SMOKING' | What the ped does; nil or false for nothing |
dealer.level | 1 | The level needed to open Lab Availability |
dealer.hours | min = 0, max = 24 | In-game hours the dealer is there |
dealer.blip | enable = true, sprite = 280, color = 0, scale = 0.8, label = 'Lab Shop' | The dealer's blip. It shows whenever blip.enable is on, even with the dealer off. |
Cooking
| Option | Default | What it does |
|---|---|---|
cooking.unique | true | Every player gets their own gasoline and cement windows. false uses each step's range for everyone. See purity. |
cooking.dispatch.table | chance = 5, sprite = 133, color = 1, scale = 1.0, radius = 50 | The chance, in percent, that choosing a table step alerts police, and the alert's blip |
cooking.dispatch.lab | The same | The same for lab steps |
cooking.table and cooking.lab are the steps under Production, in order. Each step looks like this:
[2] = {
title = locale('table-menu.add-gas-title'),
description = locale('table-menu.add-gas-desc'),
icon = 'fas fa-gas-pump',
iconColor = '',
gasoline = 'ls_gasoline',
range = { min = 5, max = 9 },
penalty = 25,
required = {
{ item = 'ls_coca_ground', quantity = 5, remove = true },
},
add = {
{ item = 'ls_coca_base_unf', quantity = 1, metatype = 'purity' },
},
xp = { min = 1, max = 3 },
event = { name = 'lation_coke:table:addGasoline' }
},| Field | What it does |
|---|---|
title, description | The row in Production, from locales/en.json |
icon, iconColor | The row's icon |
required | What the step takes: item, quantity, remove, and metatype = 'purity' on an item that carries purity. Add your own items here. Process Leaves takes its items whatever remove says. |
add | What the step gives, with metatype = 'purity' to pass the purity on. Package uses min and max in place of quantity. |
xp | XP for the step. min = 0, max = 0, or no xp, gives none. |
event | The event the row runs: name, plus server = true to run it as a server event. See custom steps. |
gasoline, cement | The item whose durability the step's slider takes from |
range | The window of amounts that keeps purity, used while cooking.unique is off |
penalty | On Add Gasoline and Add Cement, the most purity the step can take off. On Cut Brick, the percent of purity a cut takes off. |
duration | Minutes a timed step takes (Heat & Dry, Cook Coke) |
empty_baggy | The item Package uses, one per bag |
cutting_agent | The item Cut Brick uses |
On Cut Brick and Package, required and add list each brick and what it becomes in the same order, and the player picks a brick.
The shipped table steps (cooking.table):
| # | Step | Takes | Gives | Time | XP | Purity |
|---|---|---|---|---|---|---|
| 1 | Process Leaves | 20 ls_coca_leaf | 1 ls_coca_ground | 1-3 | ||
| 2 | Add Gasoline | 5 ls_coca_ground | 1 ls_coca_base_unf | 1-3 | range 5-9, penalty 25 | |
| 3 | Add Cement | 1 ls_coca_base_unf | 1 ls_coca_base | 1-3 | range 15-19, penalty 25 | |
| 4 | Heat & Dry | 1 ls_coca_base | 1 ls_cocaine_brick | 60 min | 10-30, to the table's owner | |
| 5 | Package | 1 ls_cocaine_brick | 10-20 ls_cocaine_bag | 2-5 | ||
| 6 | Cook Coke, commented out | 1 ls_cocaine_brick, 1 ls_baking_soda | 1 ls_crack_brick | 60 min | 5-15 | |
| 7 | Cut Brick, commented out | 1 cocaine or crack brick, 1 ls_baking_soda | 2 of that brick | 1-3 | penalty 50 |
The shipped lab steps (cooking.lab):
| # | Step | Takes | Gives | Time | XP | Purity |
|---|---|---|---|---|---|---|
| 1 | Process Leaves | 20 ls_coca_leaf | 1 ls_coca_ground | 2-4 | ||
| 2 | Add Gasoline | 5 ls_coca_ground | 1 ls_coca_base_unf | 2-4 | range 5-9, penalty 20 | |
| 3 | Add Cement | 1 ls_coca_base_unf | 1 ls_coca_base | 2-4 | range 15-19, penalty 20 | |
| 4 | Heat & Dry | 1 ls_coca_base | 1 ls_cocaine_brick | 45 min | 25-50 | |
| 5 | Cook Coke | 1 ls_cocaine_brick, 1 ls_baking_soda | 1 ls_crack_brick | 30 min | 5-15 | |
| 6 | Cut Brick | 1 cocaine or crack brick, 1 ls_baking_soda | 2 of that brick | 1-3 | penalty 35 | |
| 7 | Package | 1 cocaine or crack brick | 10-20 ls_cocaine_bag or ls_crack_bag | 3-6 |
Each step plays the animation with its number in animations.table or animations.lab in config/client.lua, so keep the two in line when you add or move steps.
Consumables
consumables is keyed by item. ls_cocaine_bag and ls_crack_bag ship with the same values:
| Field | Default | What it does |
|---|---|---|
usable | true | Makes the item usable |
level | 1 | The level needed to use it |
effects.health | enable = false, amount = 50 | Health added, up to 200 |
effects.armor | enable = true, amount = 100, max = 100 | Armor added, up to max |
effects.speed | enable = true, multiplier = 1.49, duration = 30000 | Sprint speed (1.49 at most) for duration milliseconds |
effects.screen | enable = true, effect = 'stoned_monkeys', duration = 30000 | A screen effect (timecycle modifier) |
effects.walk | enable = true, clipset = 'move_m@drunk@a', duration = 30000 | A walking style |
effects.shake | enable = true, name = 'DRUNK_SHAKE', intensity = 2.0, duration = 30000 | A camera shake |
Another item added with the same fields becomes usable too.
config/client.lua
Placement controls
| Option | Default | What it does |
|---|---|---|
controls.speed | 0.025 | How far a table moves each frame. Plants always move 0.025. |
controls.rotateL | 44 (Q) | Turns a table left |
controls.rotateR | 38 (E) | Turns a table right |
controls.forward | 32 (W) | Moves forward |
controls.backward | 33 (S) | Moves back |
controls.left | 34 (A) | Moves left |
controls.right | 35 (D) | Moves right |
controls.cancel | 73 (X) | Cancels |
controls.confirm | 22 (Space) | Puts it down |
controls.disable | 30, 31, 44, 22, 200 | Controls turned off while placing |
Values are control IDs. The controls shown on screen are text in locales/en.json (textui), so change them with the keys.
Security cameras
| Option | Default | What it does |
|---|---|---|
cameras.speed | 0.15 | How fast the camera turns and zooms |
cameras.timecycle | 'scanline_cam_cheap' | The camera's screen effect |
cameras.controls | panUp = 32, panDown = 33, panLeft = 34, panRight = 35, zoomIn = 44, zoomOut = 38, exit = 177 | W, S, A and D turn the camera. zoomIn (Q) widens the view and zoomOut (E) narrows it. Backspace leaves. |
cameras.disable | 32, 33, 34, 35, 44, 38, 29, 30, 31 | Controls turned off while watching |
cameras.limits | pitch = 30.0, yaw = 45.0, fov = { min = 35.0, max = 80.0 } | How far the camera turns up and down and to each side, and how far it zooms |
Lifetime statistics
| Option | Default | What it does |
|---|---|---|
stats.leaves | true | The Leaves line |
stats.grown | true | The Plants line |
stats.cement | true | The Cement line |
stats.bricks | true | The Bricks line |
With all four false, Lifetime Statistics leaves the menus.
Animations
animations holds every progress bar: label, description, icon, duration (milliseconds), position, useWhileDead, canCancel, steps (shown by lation ui), disable, anim and prop. Their labels are written here, not in the locale file.
| Entry | Label | Duration |
|---|---|---|
searching | Searching.. | 6000 |
use_table | Placing table.. | 1500 |
table[1] to table[7] | Processing leaves.., Adding gasoline.., Adding cement.., Placing down.., Packaging.., Placing down.., Cutting.. | 15000, 15000, 15000, 1500, 15000, 1500, 10000 |
lab[1] to lab[7] | Processing leaves.., Adding gasoline.., Adding cement.., Placing down.., Placing down.., Cutting.., Packaging.. | 10000, 10000, 10000, 1500, 1500, 10000, 10000 |
pickup_table | Picking up table.. | 1500 |
place_seed | Placing seed.. | 1200 |
watering.part1 | Watering.. | 4000 |
fertilizing.part1 | Fertilizing.. | 4000 |
harvesting | Harvesting.. | 4000 |
destroy_plant | Destroying.. | 4000 |
take_cement | Taking cement.. | 1500 |
use_drug | Snorting.. | 4500 |
watering.part2 and fertilizing.part2 hold the can and sack props and their particles. manage_lab, raid_entry, raid_stash and busy are looping animations with no bar.
config/server.lua
| Option | Default | What it does |
|---|---|---|
logs.service | 'none' | 'fivemanage' (needs fmsdk), 'fivemerr' (needs fm-logs), 'discord' or 'none' |
logs.screenshots | false | Adds a screenshot to each log, on Fivemanage and Fivemerr |
logs.discord.name | 'Coke Logs' | The webhook's name |
logs.discord.link | '' | The webhook URL |
logs.discord.image | An imgur link | The webhook's picture |
logs.discord.footer | An imgur link | The footer icon |
Each event in logs.events is off by default:
| Event | Logged when |
|---|---|
leaves_harvested | A player searches leaves from the field |
cement_collected | A player takes cement |
table_placed | A player places a table |
table_brick | A player takes a brick from a table |
table_packaged | A player packages a brick at a table |
table_removed | A player packs up a table |
lab_purchase | A player buys a lab |
lab_brick | A player takes a brick from a lab station |
lab_packaged | A player packages a brick in a lab |
lab_upgrade | An upgrade finishes while someone is in the lab |
lab_door | A player locks or unlocks a lab |
lab_transfer | A player hands a lab to another |
lab_sold | A player sells a lab |
config/icons.lua
Font Awesome icons and colors for every prompt, menu row, input and text UI, such as search_coca = 'fas fa-leaf' and pack_up_color = '#FF5555'. The cooking steps' icons are in cooking, and the shop items' icons in shop.items.
Text UI
The placement and camera controls show through the text UI set at the top of client/functions.lua:
-- Options: 'lation_ui', 'ox_lib', 'jg-textui', 'okokTextUI', 'qbcore' & 'custom'
local textui = 'ox_lib'Language
Every message, menu, prompt, alert, log and dispatch text is in locales/en.json. ox_lib loads the file named by its ox:locale convar, so for another language copy en.json to your language's code (such as de.json), translate it, and set setr ox:locale de in server.cfg. Progress bar labels are in config/client.lua, and blip names and lab descriptions in config/shared.lua.
Still stuck? Ask in our Discord: the people who write the scripts answer.
Last updated
Making coke
How players gather coca and cement, grow plants, cook bricks at portable tables and in labs, what sets purity, and how labs are bought, upgraded, raided and sold in coke processing.
Developers
The coke processing client and server exports, the notify event, the hooks in its open files, custom cooking steps and the shapes of its player, plant, table and lab data.