Frameworks
Supports QBCore & ESX
Can also be setup as Standalone to use any other framework
Inventories
Currently supports qb-inventory, ox_inventory, origen_inventory and qs_inventory
If your inventory is not supported, just make a ticket in my discord and I'll add support for it
CREATETABLEIFNOTEXISTS`drugmaking_plants` (`id`int(11) NOT NULL AUTO_INCREMENT,`owner`varchar(80) NOT NULL,`coords` longtext NOT NULL,`stage`int(11) NOT NULLDEFAULT0,`type`varchar(50) NOT NULLDEFAULT'0',`soil` double NOT NULLDEFAULT0,`seed` double NOT NULLDEFAULT0,`water` double NOT NULLDEFAULT0,`fertilizer` double NOT NULLDEFAULT0,`bucket`int(11) NOT NULLDEFAULT0,`rack_coords` longtext NOT NULLDEFAULT'{}',`light_coords` longtext NOT NULLDEFAULT'{}',PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=60DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;CREATETABLEIFNOTEXISTS`drugmaking_stations` (`id`int(11) NOT NULL AUTO_INCREMENT,`owner`varchar(80) NOT NULL,`coords`varchar(255) DEFAULTNULL,`bucket`int(11) DEFAULTNULL,`type`varchar(50) DEFAULTNULL,PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=30DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;
Copy and paste all the items into.
If you´re using ox_inventory, choose the Ox inventory items
If you´re using qb-inventory, choose the QB items
Ox inventory items
QB itemsESX itemsQS items
Config
Config.lua
How can I add new drugs?
It is possible to add new drugs, however, due to the complex object handling for each drug, you can only use the premade templates when creating new ones. Weed and cocaine follow a similar structure. The available templates under Config.Drugs is "weed" and "cocaine". Below, I’ll explain the process of creating new drugs in more detail.
IMPORTANT
The ['example-drug'] and [1] = 'your-seed-item' must be unique and cannot share names with any other drug. This is because, when planting, the script checks which seed item was used and refers back to the corresponding ['example-drug'], which then handles all related processes.
For Developers
Bucketing
Use the following event when you switch buckets for players in your housing/apartment.
The event should be triggered from the client.
Replace bucket with the new bucket
This event is not needed anymore since update 1.3.0, bucket changes is now being handled automatically by the script.
The following event checks for deleted objects and incorrect positions. It can be called from for example your housing script when a players enters an interior. This loads deleted objects and fix incorrect positions.
Config = {}
Config.Debug = false
-- Setting the Framework to qb will require qb-inventory.
-- Setting the Framework to esx will require esx_inventory.
-- Setting Config.Inventory to 'ox_inventory' will overwrite the framework functions and use the inventory functions instead.
Config.Framework = 'qb' -- qb or esx
Config.Inventory = 'ox_inventory' -- ox_inventory, origen_inventory, qs-inventory or nil to use framework functions
Config.ImagesPath = 'nui://ox_inventory/web/images/item_name.png' -- "nui://ox_inventory/web/images/item_name.png" or "nui://qb-inventory/html/images/item_name.png" or your own path
Config.Target = 'ox_target' -- qb-target or ox_target
Config.Locale = 'en' -- en or sv
Config.MaxPlaceDistance = 10.0 -- Sets the maximum distance from the ped at which a prop can be placed
Config.OutlineObjects = true -- If objects should display an outline drawing the prop or not.
Config.RackGrowthBonus = 0.25 -- Faster growth with rack + growlight. Default: 25%
Config.BaseGrowthTimePerStage = 5 -- Base growth time in minutes per stage. Default: 5 minutes
Config.WaterConsumptionPercent = 40 -- How much water that is consumed per stage. This means that somewhere in stage 2 the plant will need to be watered. Default: 40%
Config.MixingTime = 10 -- How many seconds it takes to mix one item. Fully maxed mixing then means 10x10 = 100 seconds
Config.CauldronTime = 10 -- How many seconds it takes to cauldron one item. Fully maxed mixing then means 10x10 = 100 seconds
Config.OvenTime = 60 -- How many seconds it takes for items in the oven to finish. Default: 60 seconds
Config.AllowExplosion = false -- If the explosion should be allowed when overheating at the methtable.
Config.CopAlerts = { -- Dispatch alerts for for each action. Add your own alerts in client/open/open_functions.lua
['planting'] = { chance = 0.2, enabled = false }, -- Chance of the function being called. 0.2 = 20% chance
['harvesting'] = { chance = 0.2, enabled = false },
['cauldron'] = { chance = 0.2, enabled = false },
['meth_table'] = { chance = 0.2, enabled = false },
['meth_oven'] = { chance = 0.2, enabled = false },
['mixing'] = { chance = 0.2, enabled = false },
['packaging'] = { chance = 0.2, enabled = false },
}
Config.Harvesting = {
['weed'] = {
template = 'weed', -- The template used for this process. 'weed' or 'cocaine' is available as of right now
budModel = 'hd_prop_weed_harvestbud', -- The model of the bud that will be displayed when the plant is harvested
outputItem = 'hd_weed_bud', -- The item that will be added when plant has been harvested
defaultBuds = 6, -- The number of buds that will be visually displayed with a fertilized plant
fertilizerBuds = 10, -- The number of buds that will be visually displayed when the plant is not fertilized
outcomePerBud = 1, -- The amount of items that the player will recieve per bud harvested
requiredItems = {
[0] = 'hd_soil_bag',
[1] = 'hd_weed_seed',
[2] = 'hd_full_wateringcan',
[3] = 'hd_fertilizer_bag'
},
prepPropStages = {
[0] = 'hd_prop_pot_empty',
[1] = 'hd_prop_pothole',
[2] = 'hd_prop_pot_full',
[3] = 'hd_prop_pot_full',
[4] = 'hd_prop_pot_full',
},
propStages = {
[0] = 'hd_prop_pot_full',
[1] = 'hd_prop_weed_stage_01',
[2] = 'hd_prop_weed_stage_02',
[3] = 'hd_prop_weed_stage_03',
[4] = 'hd_prop_weed_stage_04',
},
},
['cocaine'] = {
template = 'cocaine',
budModel = 'hd_prop_coke_leaf',
outputItem = 'hd_cocaine_leaf',
defaultBuds = 6,
fertilizerBuds = 10,
outcomePerBud = 1,
requiredItems = {
[0] = 'hd_soil_bag',
[1] = 'hd_cocaine_seed',
[2] = 'hd_full_wateringcan',
[3] = 'hd_fertilizer_bag'
},
prepPropStages = {
[0] = 'hd_prop_pot_empty',
[1] = 'hd_prop_pothole',
[2] = 'hd_prop_pot_full',
[3] = 'hd_prop_pot_full',
[4] = 'hd_prop_pot_full',
},
propStages = {
[0] = 'hd_prop_pot_full',
[1] = 'hd_prop_coke_stage_01',
[2] = 'hd_prop_coke_stage_02',
[3] = 'hd_prop_coke_stage_03',
[4] = 'hd_prop_coke_stage_04',
},
},
}
Config.MethTable = {
['meth'] = {
requiredItems = { -- The items that are required to start the process
{
name = 'hd_acid', -- The name of the item that is required
amount = 1 -- The amount of the item that is required
},
{
name = 'hd_phosphorus',
amount = 1
},
{
name = 'hd_redpills',
amount = 1
}
},
outputItem = 'hd_meth_liquid', -- The item that will be added when the process is finished
outputItemLabel = 'Liquid Meth',
outputItemAmount = 10, -- The outcome amount of the outputItem item
purity = { -- If none of the values are met, the purity will be set to 'poor'
['standard'] = {
acid = { lowest = 30, highest = 60 },
phosphorus = { lowest = 50, highest = 100 },
},
['premium'] = {
acid = { lowest = 60, highest = 90 },
phosphorus = { lowest = 100, highest = 150 },
},
}
},
}
Config.MethOven = {
['hd_meth_poor'] = { -- The name of the item that will be added when the process is finished
liquidAmount = 1, -- The amount of the liquid item that is required to start the process
liquid = 'hd_meth_liquid_poor', -- The item that is required to start the process
outputAmount = 10, -- The amount of the outputItem item that will be added when the process is finished
},
['hd_meth_standard'] = {
liquidAmount = 1,
liquid = 'hd_meth_liquid_standard',
outputAmount = 10,
},
['hd_meth_premium'] = {
liquidAmount = 1,
liquid = 'hd_meth_liquid_premium',
outputAmount = 10,
},
}
Config.Cauldron = {
[1] = {
itemToCauldron = 'hd_cocaine_leaf',
itemToMix = 'hd_gasoline', -- Only removes 1 item
outputItem = 'hd_cocaine_bud',
propType = 'hd_prop_coke_leaf',
},
}
Config.Items = {
['drug_pot_empty'] = {
label = 'Tom kruka',
model = 'hd_prop_pot_empty',
},
['packaging_table'] = {
label = 'Packstation',
model = 'hd_prop_weed_table',
},
['mixing_station'] = {
label = 'Mixing Station',
model = 'hd_prop_mixingbot',
},
['cauldron'] = {
label = 'Kruka',
model = 'hd_prop_cauldron',
},
['meth_table'] = {
label = 'Meth Table',
model = 'hd_prop_methtable',
},
['meth_oven'] = {
label = 'Meth Oven',
model = 'hd_props_oven',
},
}
Config.PublicStations = { -- Add public stations here
['mixing_stations'] = {
--[[
{
coords = vector4(-321.6, 180.77, 87.92, 181.96),
bucket = 0,
},
]]
},
['packaging_stations'] = {
--[[
{
coords = vector4(-322.21, 176.42, 87.92, 16.41),
bucket = 0,
}
]]
},
['cauldrons'] = {
--[[
{
coords = vector4(-317.07, 178.83, 87.92, 97.15),
bucket = 0,
}
]]
},
['meth_tables'] = {
--[[
{
coords = vector4(-972.44, -2962.45, 12.95, 344.52),
bucket = 0,
}
]]
},
['meth_ovens'] = {
--[[
{
coords = vector4(-967.95, -2962.12, 12.95, 9.71),
bucket = 0,
}
]]
},
}
Config.PrepPropStagesUndefined = { -- This is only used if the plant is not yet defined with a drug type. [0] and [1] should be the only ones needed
[0] = 'hd_prop_pot_empty',
[1] = 'hd_prop_pothole',
[2] = 'hd_prop_pot_full',
[3] = 'hd_prop_pot_full',
[4] = 'hd_prop_pot_full',
}
Config.Packaging = { -- Items that can be packaged into bags
emptyBag = 'hd_zipbag', -- Define your own item name or leave as is
-- Weed buds
['hd_weed_bud'] = {
model = 'hd_prop_weed_bud', -- The bud drag model
outcomeItem = 'hd_weed_bud_zipped', -- The item that will be added when the packaging is finished
},
['hd_weed_gasoline'] = {
model = 'hd_prop_weed_bud',
outcomeItem = 'hd_weed_gasoline_zipped',
},
['hd_weed_gasoline_sprunk'] = {
model = 'hd_prop_weed_bud',
outcomeItem = 'hd_weed_gasoline_sprunk_zipped',
},
-- Cocaine buds
['hd_cocaine_bud'] = {
model = 'hd_prop_cocaine_bud',
outcomeItem = 'hd_cocaine_bud_zipped',
},
['hd_cocaine_gasoline'] = {
model = 'hd_prop_cocaine_bud',
outcomeItem = 'hd_cocaine_gasoline_zipped',
},
['hd_cocaine_gasoline_sprunk'] = {
model = 'hd_prop_cocaine_bud',
outcomeItem = 'hd_cocaine_gasoline_sprunk_zipped',
},
-- Meth Crystals
['hd_meth_poor'] = {
model = 'hd_prop_meth_crystal',
outcomeItem = 'hd_meth_poor_zipped',
},
['hd_meth_poor_gasoline'] = {
model = 'hd_prop_meth_crystal',
outcomeItem = 'hd_meth_poor_gasoline_zipped',
},
['hd_meth_poor_gasoline_sprunk'] = {
model = 'hd_prop_meth_crystal',
outcomeItem = 'hd_meth_poor_gasoline_sprunk_zipped',
},
['hd_meth_standard'] = {
model = 'hd_prop_meth_crystal',
outcomeItem = 'hd_meth_standard_zipped',
},
['hd_meth_premium'] = {
model = 'hd_prop_meth_crystal',
outcomeItem = 'hd_meth_premium_zipped',
},
}
Config.MixingTypes = {
['weed'] = {
model = 'hd_prop_weed_bud',
},
['cocaine'] = {
model = 'hd_prop_cocaine_bud',
},
['meth'] = {
model = 'hd_prop_meth_crystal',
},
}
Config.Mixing = {
-- Example strain for weed (2 stages)
[1] = {propType = 'weed', drugItem = 'hd_weed_bud', mixItem = 'hd_gasoline', outputItem = 'hd_weed_gasoline'},
[2] = {propType = 'weed', drugItem = 'hd_weed_gasoline', mixItem = 'hd_sprunk', outputItem = 'hd_weed_gasoline_sprunk'},
-- Example strain for cocaine (2 stages)
[3] = {propType = 'cocaine', drugItem = 'hd_cocaine_bud', mixItem = 'hd_gasoline', outputItem = 'hd_cocaine_gasoline'},
[4] = {propType = 'cocaine', drugItem = 'hd_cocaine_gasoline', mixItem = 'hd_sprunk', outputItem = 'hd_cocaine_gasoline_sprunk'},
-- Example strain for meth (2 stages) Only configed with poor purity
[5] = {propType = 'meth', drugItem = 'hd_meth_poor', mixItem = 'hd_gasoline', outputItem = 'hd_meth_poor_gasoline'},
[6] = {propType = 'meth', drugItem = 'hd_meth_poor_gasoline', mixItem = 'hd_sprunk', outputItem = 'hd_meth_poor_gasoline_sprunk'},
}
['example-drug'] = {
template = 'weed', -- The template used for this process. 'weed' or 'cocaine' is available as of right now
budModel = 'hd_prop_weed_harvestbud', -- The model of the bud that will be displayed when the plant is harvested
outputItem = 'your-output-item', -- The item that will be added when plant has been harvested
defaultBuds = 6, -- The number of buds that will be visually displayed with a fertilized plant
fertilizerBuds = 10, -- The number of buds that will be visually displayed when the plant is not fertilized
outcomePerBud = 1, -- The amount of items that the player will recieve per bud harvested
requiredItems = {
[0] = 'hd_soil_bag', -- Required item in first stage planting
[1] = 'your-seed-item', -- Required item in second stage planting
[2] = 'hd_full_wateringcan', -- Required item in third stage planting
[3] = 'hd_fertilizer_bag' -- Required item in fourth stage planting
},
prepPropStages = { -- I highly recommend not to edit the props below since it will cause issues with positions
[0] = 'hd_prop_pot_empty',
[1] = 'hd_prop_pothole',
[2] = 'hd_prop_pot_full',
[3] = 'hd_prop_pot_full',
[4] = 'hd_prop_pot_full',
},
propStages = { -- I highly recommend not to edit the props below since it will cause issues wit
[0] = 'hd_prop_pot_full',
[1] = 'hd_prop_weed_stage_01',
[2] = 'hd_prop_weed_stage_02',
[3] = 'hd_prop_weed_stage_03',
[4] = 'hd_prop_weed_stage_04',
},
},
OpenFunctions = {
--@param message string
--@param type string (success, error, info)
ShowNotification = function(message, type)
local data = {
description = message,
type = type
}
lib.notify(data)
end,
--@param action string (harvesting, mixing, packaging, cauldron)
--@return boolean (true if action is allowed, false otherwise)
IsActionAllowed = function(action)
return true
end,
--@param type string (planting, harvesting, cauldron, meth_table, meth_oven, mixing, packaging)
DispatchAlert = function(type)
-- Add your dispatch alerts here
--print('Dispatching alert for ' .. type)
end,
--@return boolean
IsPlayerInAllowedArea = function()
-- Implement you own logic here to check for example if the player is inside a house/apartment
return true
end,
}
OpenFunctions = {
--@param data table
--@field source number
--@field action string (harvesting, mixing, packaging, meth_table, meth_oven, cauldron)
--@field item string (item recieved)
--@field amount number (amount of item recieved)
--@field drugType string (only for harvesting)
OnActionCompleted = function(data)
-- This function is called every time an action is completed and can be implemented in your own scripts to for example give rep/xp
-- print(json.encode(data))
end,
--@param src number
--@param message string
--@param type string (success, error, info)
ShowNotification = function(src, message, type)
local data = {
description = message,
type = type
}
TriggerClientEvent('ox_lib:notify', src, data)
end,
}