Inicio › Documentación › Objetos · origen_ilegalv2

Objetos · origen_ilegalv2

origen_ilegalv2 requiere que se registren 18 objetos únicos en tu inventario para que el recurso funcione correctamente. Copia el bloque que corresponda a tu sistema de inventario y pégalo en el fichero adecuado.

empty_weed_bag es compartido entre el laboratorio de meta y el de coca. Regístralo una sola vez.

Los items graffiti_spray y graffiti_eraser solo son necesarios cuando Config.Graffiti.Enable = true.


Mapa de objetos por laboratorio

Objeto Laboratorio Función Utilizable
ephedrine Meta Ingrediente de cocinado No
acetone Meta Ingrediente de cocinado No
empty_weed_bag Meta / Coca Ingrediente de embolsado (compartido) No
methbags Meta Producto final Venta de drogas
coca_leaf Coca Ingrediente de procesado No
coke Coca Intermedio (salida de make_powder, entrada de cut_coke) No
bakingsoda Coca Ingrediente de corte No
loosecoke Coca Intermedio (salida de cut_coke, entrada de bag_coke) No
cokebaggy Coca Producto final Venta de drogas
wetcannabis Marihuana Resultado de la cosecha · ingrediente de secado No
drycannabis Marihuana Resultado del secado · ingrediente de molido No
weedgrinder Marihuana Herramienta obligatoria — no se consume No
grindedweed Marihuana Resultado del molido · ingrediente de embolsado No
bluntwrap Marihuana Ingrediente de embolsado No
blunt Marihuana Producto final Venta de drogas
ilegal_cad Banda Credencial del panel de banda — no se consume al usarse Sí
graffiti_spray Grafiti Lata de spray — se consume al colocar un tag Sí
graffiti_eraser Grafiti Trapo de limpieza — se consume al borrar un grafiti Sí

Los objetos marcados como Sí abren un menú o inician una acción cuando el jugador los usa. En ox_inventory necesitan la configuración adicional descrita en Objetos utilizables en ox_inventory.

Los objetos marcados como Venta de drogas solo pasan a ser utilizables cuando figuran en Config.DrugSales.DrugList.


ox_inventory

Añade las siguientes entradas a ox_inventory/data/items.lua:

En ox_inventory el icono debe declararse dentro de la tabla client como client = { image = '...' }. Un campo image de nivel superior lo ignora el inventario y el objeto recurrirá a <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' },
},

Objetos utilizables en ox_inventory

ox_inventory no lee el registro del framework que usan QBCore.Functions.CreateUseableItem o ESX.RegisterUsableItem cuando un objeto declara su propio handler. Para que los objetos utilizables de este recurso funcionen de forma nativa en ox_inventory, hacen falta dos piezas.

1. Declara el export en el objeto

Los tres objetos utilizables de arriba ya lo incluyen:

lua
consume = 0,
server  = { export = 'origen_ilegalv2.<item_name>' },

consume = 0 es obligatorio. Al declarar server.export, ox_inventory establece consume = 1 automáticamente, lo que elimina el objeto del inventario del jugador en cada uso. Eso quitaría el CAD de banda (una credencial permanente) y consumiría los objetos de grafiti dos veces, porque el recurso ya los elimina por sí mismo tras una acción exitosa.

Usa el número 0, no false ni nil. En Lua 0 es verdadero, así que es el único valor que a la vez evita el consumo automático y sigue activando el handler del objeto.

2. Añade el fichero de bridge de exports

Crea custom/server/ox_usable_exports.lua dentro del recurso. El patrón custom/server/*.lua ya está declarado en fxmanifest.lua, así que no hace falta cambiar el manifest, y la carpeta figura en escrow_ignore, por lo que el fichero sobrevive a las actualizaciones del recurso.

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

El fichero envuelve Framework.RegisterUsableItem, de modo que todos los objetos que registra el recurso obtienen automáticamente su export de ox_inventory. Esto cubre también las drogas creadas en tiempo de ejecución desde el panel de administración.

El registro original del framework se conserva como alternativa. No hay doble ejecución: ox_inventory solo recurre al registro del framework cuando el objeto no declara consume, y estos objetos sí lo declaran.

ox_inventory no puede crear objetos en tiempo de ejecución. Una droga añadida desde el panel de administración obtiene su handler de uso, pero el objeto en sí debe añadirse manualmente a ox_inventory/data/items.lua, seguido de un reinicio del recurso.


QBCore

Añade las siguientes entradas a 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

Ejecuta el siguiente SQL contra tu base de datos (o pégalo en 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);

En ESX, rare = 1 marca un objeto como no apilable en algunas implementaciones antiguas de UI. Solo weedgrinder e ilegal_cad están marcados como raros/únicos en todos los formatos porque son herramientas, no consumibles.


Imágenes de los objetos

Coloca los ficheros de imagen .png en la carpeta de imágenes de tu recurso de inventario:

Los nombres de fichero deben coincidir exactamente con el campo image (distingue mayúsculas y minúsculas en servidores Linux):

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