Início › Documentação › Itens · origen_ilegalv2
O origen_ilegalv2 requer que sejam registados 18 itens únicos no teu inventário para que o recurso funcione corretamente. Copia o bloco que corresponde ao teu sistema de inventário e cola-o no ficheiro adequado.
O empty_weed_bag é partilhado entre o laboratório de meta e o de coca. Regista-o apenas uma vez.
Os itens graffiti_spray e graffiti_eraser só são necessários quando Config.Graffiti.Enable = true.
| Item | Laboratório | Função | Utilizável |
|---|---|---|---|
ephedrine |
Meta | Ingrediente de cozedura | Não |
acetone |
Meta | Ingrediente de cozedura | Não |
empty_weed_bag |
Meta / Coca | Ingrediente de ensacamento (partilhado) | Não |
methbags |
Meta | Produto final | Venda de droga |
coca_leaf |
Coca | Ingrediente de processamento | Não |
coke |
Coca | Intermédio (saída de make_powder, entrada de cut_coke) | Não |
bakingsoda |
Coca | Ingrediente de corte | Não |
loosecoke |
Coca | Intermédio (saída de cut_coke, entrada de bag_coke) | Não |
cokebaggy |
Coca | Produto final | Venda de droga |
wetcannabis |
Erva | Resultado da colheita · ingrediente de secagem | Não |
drycannabis |
Erva | Resultado da secagem · ingrediente de moagem | Não |
weedgrinder |
Erva | Ferramenta obrigatória — não é consumida | Não |
grindedweed |
Erva | Resultado da moagem · ingrediente de ensacamento | Não |
bluntwrap |
Erva | Ingrediente de ensacamento | Não |
blunt |
Erva | Produto final | Venda de droga |
ilegal_cad |
Gangue | Credencial do painel da gangue — não é consumida ao usar | Sim |
graffiti_spray |
Graffiti | Spray — consumido ao colocar uma tag | Sim |
graffiti_eraser |
Graffiti | Pano de limpeza — consumido ao remover um graffiti | Sim |
Os itens marcados com Sim abrem um menu ou iniciam uma ação quando o jogador os usa. No ox_inventory precisam da configuração adicional descrita em Itens utilizáveis no ox_inventory.
Os itens marcados com Venda de droga só passam a ser utilizáveis quando constam em Config.DrugSales.DrugList.
Adiciona as seguintes entradas a ox_inventory/data/items.lua:
No ox_inventory o ícone tem de ser declarado dentro da tabela client como client = { image = '...' }. Um campo image de nível superior é ignorado pelo inventário e o item recorrerá a <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' },
},O ox_inventory não lê o registo do framework usado por QBCore.Functions.CreateUseableItem ou ESX.RegisterUsableItem quando um item declara o seu próprio handler. Para que os itens utilizáveis deste recurso funcionem nativamente no ox_inventory, são necessárias duas peças.
Os três itens utilizáveis acima já o incluem:
consume = 0,
server = { export = 'origen_ilegalv2.<item_name>' },consume = 0 é obrigatório. Ao declarar server.export, o ox_inventory define consume = 1 automaticamente, o que elimina o item do inventário do jogador em cada utilização. Isso removeria o CAD da gangue (uma credencial permanente) e consumiria os itens de graffiti duas vezes, porque o recurso já os remove por si após uma ação bem-sucedida.
Usa o número 0, não false nem nil. Em Lua, 0 é verdadeiro, pelo que é o único valor que ao mesmo tempo evita o consumo automático e continua a acionar o handler do item.
Cria custom/server/ox_usable_exports.lua dentro do recurso. O padrão custom/server/*.lua já está declarado em fxmanifest.lua, por isso não é preciso alterar o manifest, e a pasta consta de escrow_ignore, pelo que o ficheiro sobrevive às atualizações do recurso.
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)
endO ficheiro envolve Framework.RegisterUsableItem, pelo que todos os itens que o recurso regista obtêm automaticamente o respetivo export do ox_inventory. Isto também abrange as drogas criadas em tempo de execução a partir do painel de administração.
O registo original do framework é mantido como alternativa. Não há dupla execução: o ox_inventory só recorre ao registo do framework quando o item não declara consume, e estes itens declaram-no.
O ox_inventory não consegue criar itens em tempo de execução. Uma droga adicionada a partir do painel de administração obtém o seu handler de utilização, mas o item em si tem de ser adicionado manualmente a ox_inventory/data/items.lua, seguido de um reinício do recurso.
Adiciona as seguintes entradas a 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.' },Executa o seguinte SQL na tua base de dados (ou cola-o no 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);No ESX, rare = 1 marca um item como não empilhável em algumas implementações antigas de UI. Apenas weedgrinder e ilegal_cad estão marcados como raros/únicos em todos os formatos porque são ferramentas, não consumíveis.
Coloca os ficheiros de imagem .png na pasta de imagens do teu recurso de inventário:
Os nomes dos ficheiros têm de corresponder exatamente ao campo image (distingue maiúsculas de minúsculas em servidores Linux):
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