Items · origen_ilegalv2
origen_ilegalv2 requires 18 unique items to be registered in your inventory before the resource can operate correctly. Copy the block that matches your inventory system and paste it in the appropriate file.
empty_weed_bag is shared between the Meth Lab and the Coke Lab. Register it only once.
The graffiti_spray and graffiti_eraser items are only required when Config.Graffiti.Enable = true.
Item map by lab
| Item | Lab | Role | Usable |
|---|---|---|---|
ephedrine | Meth | Cooking input | No |
acetone | Meth | Cooking input | No |
empty_weed_bag | Meth / Coke | Bagging input (shared) | No |
methbags | Meth | Final output | Drug sales |
coca_leaf | Coke | Processing input | No |
coke | Coke | Intermediate (output of make_powder, input of cut_coke) | No |
bakingsoda | Coke | Cutting agent input | No |
loosecoke | Coke | Intermediate (output of cut_coke, input of bag_coke) | No |
cokebaggy | Coke | Final output | Drug sales |
wetcannabis | Weed | Plant harvest output · drying input | No |
drycannabis | Weed | Drying output · grinding input | No |
weedgrinder | Weed | Required tool — not consumed | No |
grindedweed | Weed | Grinding output · bagging input | No |
bluntwrap | Weed | Bagging input | No |
blunt | Weed | Final output | Drug sales |
ilegal_cad | Gang | Gang panel credential — not consumed on use | Yes |
graffiti_spray | Graffiti | Spray can — consumed on tag placement | Yes |
graffiti_eraser | Graffiti | Cleaning rag — consumed on graffiti removal | Yes |
Items marked Yes open a menu or start an action when the player uses them. On ox_inventory they need the extra
wiring described in Usable items on ox_inventory.
Items marked Drug sales only become usable when they are listed in Config.DrugSales.DrugList.
ox_inventory
Add the following entries to ox_inventory/data/items.lua:
On ox_inventory the icon must be declared inside the client table as client = { image = '...' }.
A top-level image field is ignored by the inventory and the item will fall back to <item_name>.png.
-- ── METH LAB ──────────────────────────────────────────────────────────────────
['ephedrine'] = {
label = 'Ephedrine',
weight = 100,
stack = true,
close = true,
description = 'Chemical precursor for methamphetamine production.',
client = { image = 'ephedrine.png' },
},
['acetone'] = {
label = 'Acetone',
weight = 200,
stack = true,
close = true,
description = 'Chemical solvent. Required for the cooking process.',
client = { image = 'acetone.png' },
},
['empty_weed_bag'] = {
label = 'Empty Bag',
weight = 10,
stack = true,
close = true,
description = 'Empty plastic bag. Used for packaging products.',
client = { image = 'empty_weed_bag.png' },
},
['methbags'] = {
label = 'Meth Bags',
weight = 150,
stack = true,
close = true,
description = 'Crystallized methamphetamine ready for distribution.',
client = { image = 'methbags.png' },
},
-- ── COKE LAB ──────────────────────────────────────────────────────────────────
['coca_leaf'] = {
label = 'Coca Leaf',
weight = 50,
stack = true,
close = true,
description = 'Raw coca leaf. Primary raw material for processing.',
client = { image = 'coca_leaf.png' },
},
['coke'] = {
label = 'Base Powder',
weight = 80,
stack = true,
close = true,
description = 'Unprocessed cocaine powder. Intermediate product.',
client = { image = 'coke.png' },
},
['bakingsoda'] = {
label = 'Baking Soda',
weight = 50,
stack = true,
close = true,
description = 'Sodium bicarbonate. Cutting agent for cocaine.',
client = { image = 'bakingsoda.png' },
},
['loosecoke'] = {
label = 'Cut Cocaine',
weight = 80,
stack = true,
close = true,
description = 'Cut cocaine ready for bagging.',
client = { image = 'loosecoke.png' },
},
['cokebaggy'] = {
label = 'Cocaine Baggy',
weight = 100,
stack = true,
close = true,
description = 'Bagged cocaine ready for distribution.',
client = { image = 'cokebaggy.png' },
},
-- ── WEED LAB ──────────────────────────────────────────────────────────────────
['wetcannabis'] = {
label = 'Wet Cannabis',
weight = 100,
stack = true,
close = true,
description = 'Freshly harvested cannabis flower. Must be dried.',
client = { image = 'wetcannabis.png' },
},
['drycannabis'] = {
label = 'Dry Cannabis',
weight = 60,
stack = true,
close = true,
description = 'Dried cannabis ready for grinding.',
client = { image = 'drycannabis.png' },
},
['weedgrinder'] = {
label = 'Grinder',
weight = 200,
stack = false,
close = true,
description = 'Herb grinder. Not consumed on use.',
client = { image = 'weedgrinder.png' },
},
['grindedweed'] = {
label = 'Ground Cannabis',
weight = 40,
stack = true,
close = true,
description = 'Ground cannabis ready for bagging.',
client = { image = 'grindedweed.png' },
},
['bluntwrap'] = {
label = 'Blunt Wrap',
weight = 10,
stack = true,
close = true,
description = 'Rolling paper for blunts.',
client = { image = 'bluntwrap.png' },
},
['blunt'] = {
label = 'Blunt',
weight = 30,
stack = true,
close = true,
description = 'Rolled blunt ready for sale.',
client = { image = 'blunt.png' },
},
-- ── GANG CAD ──────────────────────────────────────────────────────────────────
['ilegal_cad'] = {
label = 'Gang CAD',
weight = 0,
stack = true,
close = false,
consume = 0,
description = 'Gang panel access credential. Not consumed on use.',
client = { image = 'ilegal_cad.png' },
server = { export = 'origen_ilegalv2.ilegal_cad' },
},
-- ── GRAFFITI ──────────────────────────────────────────────────────────────────
['graffiti_spray'] = {
label = 'Spray Can',
weight = 300,
stack = true,
close = true,
consume = 0,
description = 'Aerosol spray can. Used to tag gang graffiti. Consumed on placement.',
client = { image = 'graffiti_spray.png' },
server = { export = 'origen_ilegalv2.graffiti_spray' },
},
['graffiti_eraser'] = {
label = 'Cleaning Rag',
weight = 100,
stack = true,
close = true,
consume = 0,
description = 'Solvent-soaked rag. Used to clean graffiti tags. Consumed on use.',
client = { image = 'graffiti_eraser.png' },
server = { export = 'origen_ilegalv2.graffiti_eraser' },
},Usable items on ox_inventory
ox_inventory does not read the framework registry used by QBCore.Functions.CreateUseableItem or
ESX.RegisterUsableItem when an item declares its own handler. To make the usable items of this resource
work natively on ox_inventory, two pieces are required.
1. Declare the export on the item
The three usable items above already include it:
consume = 0,
server = { export = 'origen_ilegalv2.<item_name>' },consume = 0 is mandatory. Declaring server.export makes ox_inventory set consume = 1 automatically,
which deletes the item from the player inventory on every use. That would remove the Gang CAD (a permanent
credential) and would consume the graffiti items twice, because the resource already removes them by itself
after a successful action.
Use the number 0, not false or nil. In Lua 0 is truthy, so it is the only value that both prevents the
automatic consumption and still triggers the item handler.
2. Add the export bridge file
Create custom/server/ox_usable_exports.lua inside the resource. The custom/server/*.lua glob is already
declared in fxmanifest.lua, so no manifest change is needed, and the folder is listed in escrow_ignore,
so the file survives resource updates.
if GetResourceState('ox_inventory') ~= 'started' then return end
local bound = {}
local function buildItemData(item, inventory, slot)
local slotData = slot and inventory.items and inventory.items[slot]
return {
name = item and item.name,
label = item and item.label,
slot = slot,
count = slotData and slotData.count or 1,
metadata = slotData and slotData.metadata or {},
}
end
local function bindOxUsable(itemName, cb)
if not itemName or bound[itemName] then return end
bound[itemName] = true
exports(itemName, function(event, item, inventory, slot)
if event ~= 'usingItem' then return end
if not inventory or not inventory.player then return end
cb(inventory.id, buildItemData(item, inventory, slot))
end)
end
local baseRegister = Framework and Framework.RegisterUsableItem
if not baseRegister then
print('^1[origen_ilegalv2] Framework.RegisterUsableItem not available - ox_inventory exports not mounted^0')
return
end
Framework.RegisterUsableItem = function(itemName, cb)
baseRegister(itemName, cb)
bindOxUsable(itemName, cb)
endThe file wraps Framework.RegisterUsableItem, so every item the resource registers gets its ox_inventory
export automatically. This also covers drugs created at runtime from the admin panel.
The original framework registration is preserved as a fallback. There is no double execution: ox_inventory
only falls back to the framework registry when the item does not declare consume, and these items do.
ox_inventory cannot create items at runtime. A drug added from the admin panel gets its usable handler, but
the item itself must still be added manually to ox_inventory/data/items.lua followed by a resource restart.
QBCore
Add the following entries to qb-core/shared/items.lua:
-- ── METH LAB ──────────────────────────────────────────────────────────────────
['ephedrine'] = { name = 'ephedrine', label = 'Ephedrine', weight = 100, type = 'item', image = 'ephedrine.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Chemical precursor for methamphetamine production.' },
['acetone'] = { name = 'acetone', label = 'Acetone', weight = 200, type = 'item', image = 'acetone.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Chemical solvent. Required for the cooking process.' },
['empty_weed_bag'] = { name = 'empty_weed_bag', label = 'Empty Bag', weight = 10, type = 'item', image = 'empty_weed_bag.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Empty plastic bag. Used for packaging products.' },
['methbags'] = { name = 'methbags', label = 'Meth Bags', weight = 150, type = 'item', image = 'methbags.png', unique = false, useable = true, shouldClose = true, combinable = nil, description = 'Crystallized methamphetamine ready for distribution.' },
-- ── COKE LAB ──────────────────────────────────────────────────────────────────
['coca_leaf'] = { name = 'coca_leaf', label = 'Coca Leaf', weight = 50, type = 'item', image = 'coca_leaf.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Raw coca leaf. Primary raw material for processing.' },
['coke'] = { name = 'coke', label = 'Base Powder', weight = 80, type = 'item', image = 'coke.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Unprocessed cocaine powder. Intermediate product.' },
['bakingsoda'] = { name = 'bakingsoda', label = 'Baking Soda', weight = 50, type = 'item', image = 'bakingsoda.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Sodium bicarbonate. Cutting agent for cocaine.' },
['loosecoke'] = { name = 'loosecoke', label = 'Cut Cocaine', weight = 80, type = 'item', image = 'loosecoke.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Cut cocaine ready for bagging.' },
['cokebaggy'] = { name = 'cokebaggy', label = 'Cocaine Baggy', weight = 100, type = 'item', image = 'cokebaggy.png', unique = false, useable = true, shouldClose = true, combinable = nil, description = 'Bagged cocaine ready for distribution.' },
-- ── WEED LAB ──────────────────────────────────────────────────────────────────
['wetcannabis'] = { name = 'wetcannabis', label = 'Wet Cannabis', weight = 100, type = 'item', image = 'wetcannabis.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Freshly harvested cannabis flower. Must be dried.' },
['drycannabis'] = { name = 'drycannabis', label = 'Dry Cannabis', weight = 60, type = 'item', image = 'drycannabis.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Dried cannabis ready for grinding.' },
['weedgrinder'] = { name = 'weedgrinder', label = 'Grinder', weight = 200, type = 'item', image = 'weedgrinder.png', unique = true, useable = true, shouldClose = true, combinable = nil, description = 'Herb grinder. Not consumed on use.' },
['grindedweed'] = { name = 'grindedweed', label = 'Ground Cannabis', weight = 40, type = 'item', image = 'grindedweed.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Ground cannabis ready for bagging.' },
['bluntwrap'] = { name = 'bluntwrap', label = 'Blunt Wrap', weight = 10, type = 'item', image = 'bluntwrap.png', unique = false, useable = false, shouldClose = true, combinable = nil, description = 'Rolling paper for blunts.' },
['blunt'] = { name = 'blunt', label = 'Blunt', weight = 30, type = 'item', image = 'blunt.png', unique = false, useable = true, shouldClose = true, combinable = nil, description = 'Rolled blunt ready for sale.' },
-- ── GANG CAD ──────────────────────────────────────────────────────────────────
['ilegal_cad'] = { name = 'ilegal_cad', label = 'Gang CAD', weight = 0, type = 'item', image = 'ilegal_cad.png', unique = false, useable = true, shouldClose = false, combinable = nil, description = 'Gang panel access credential. Not consumed on use.' },
-- ── GRAFFITI ──────────────────────────────────────────────────────────────────
['graffiti_spray'] = { name = 'graffiti_spray', label = 'Spray Can', weight = 300, type = 'item', image = 'graffiti_spray.png', unique = false, useable = true, shouldClose = true, combinable = nil, description = 'Aerosol spray can. Used to tag gang graffiti. Consumed on placement.' },
['graffiti_eraser'] = { name = 'graffiti_eraser', label = 'Cleaning Rag', weight = 100, type = 'item', image = 'graffiti_eraser.png', unique = false, useable = true, shouldClose = true, combinable = nil, description = 'Solvent-soaked rag. Used to clean graffiti tags. Consumed on use.' },ESX
Run the following SQL against your database (or paste it into HeidiSQL / phpMyAdmin):
INSERT INTO `items` (`name`, `label`, `weight`, `rare`, `can_remove`) VALUES
-- METH LAB
('ephedrine', 'Ephedrine', 100, 0, 1),
('acetone', 'Acetone', 200, 0, 1),
('empty_weed_bag', 'Empty Bag', 10, 0, 1),
('methbags', 'Meth Bags', 150, 0, 1),
-- COKE LAB
('coca_leaf', 'Coca Leaf', 50, 0, 1),
('coke', 'Base Powder', 80, 0, 1),
('bakingsoda', 'Baking Soda', 50, 0, 1),
('loosecoke', 'Cut Cocaine', 80, 0, 1),
('cokebaggy', 'Cocaine Baggy', 100, 0, 1),
-- WEED LAB
('wetcannabis', 'Wet Cannabis', 100, 0, 1),
('drycannabis', 'Dry Cannabis', 60, 0, 1),
('weedgrinder', 'Grinder', 200, 1, 1),
('grindedweed', 'Ground Cannabis', 40, 0, 1),
('bluntwrap', 'Blunt Wrap', 10, 0, 1),
('blunt', 'Blunt', 30, 0, 1),
-- GANG CAD
('ilegal_cad', 'Gang CAD', 0, 0, 1),
-- GRAFFITI
('graffiti_spray', 'Spray Can', 300, 0, 1),
('graffiti_eraser', 'Cleaning Rag', 100, 0, 1);For ESX, rare = 1 marks an item as non-stackable in some legacy UI implementations. Only weedgrinder and ilegal_cad are marked rare/unique across formats because they are tools — not consumables.
Item images
Place the .png image files in the images folder of your inventory resource:
The file names must match the image field exactly (case-sensitive on Linux servers):
ephedrine.png acetone.png empty_weed_bag.png methbags.png
coca_leaf.png coke.png bakingsoda.png loosecoke.png
cokebaggy.png wetcannabis.png drycannabis.png weedgrinder.png
grindedweed.png bluntwrap.png blunt.png ilegal_cad.png
graffiti_spray.png graffiti_eraser.png