OrigenNetwork
Docs

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

ItemLabRoleUsable
ephedrineMethCooking inputNo
acetoneMethCooking inputNo
empty_weed_bagMeth / CokeBagging input (shared)No
methbagsMethFinal outputDrug sales
coca_leafCokeProcessing inputNo
cokeCokeIntermediate (output of make_powder, input of cut_coke)No
bakingsodaCokeCutting agent inputNo
loosecokeCokeIntermediate (output of cut_coke, input of bag_coke)No
cokebaggyCokeFinal outputDrug sales
wetcannabisWeedPlant harvest output · drying inputNo
drycannabisWeedDrying output · grinding inputNo
weedgrinderWeedRequired tool — not consumedNo
grindedweedWeedGrinding output · bagging inputNo
bluntwrapWeedBagging inputNo
bluntWeedFinal outputDrug sales
ilegal_cadGangGang panel credential — not consumed on useYes
graffiti_sprayGraffitiSpray can — consumed on tag placementYes
graffiti_eraserGraffitiCleaning rag — consumed on graffiti removalYes

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.

luaox_inventory/data/items.lua
-- ── 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:

lua
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.

luaorigen_ilegalv2/custom/server/ox_usable_exports.lua
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)
end

The 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:

luaqb-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):

sqlESX — INSERT INTO items
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):

text
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