Armi Custom con ESX + ox_inventory
INFO
Dopo aver registrato l’arma come item (file 02), vediamo come integrarla completamente: negozio, dare via script, crafting.
| Obiettivo | Dettagli |
|---|---|
| Cosa imparerai | • Creare negozi armi con ox_inventory (data/shops.lua / RegisterShop)• Gestire acquisti e crafting di armi custom • Notifiche da server con ox_lib |
| Prerequisiti | • Aver registrato un’arma in ox_inventory (file 02) • Conoscenza base di ESX events • ox_target installato |
1. Negozio Armi con ox_inventory
ox_inventory carica i negozi da ox_inventory/data/shops.lua. Il formato reale usa name (label), inventory (item + prezzo) e targets/locations (dove aprirsi).
Esempio: Armeria
-- ox_inventory/data/shops.lua
return {
['weapon_shop_basic'] = {
name = 'Armeria',
blip = { id = 110, colour = 1, scale = 0.7 },
targets = {
{
loc = vec3(250.0, -150.0, 30.0), -- centro del negozio
length = 1.5, width = 1.5, heading = 0,
minZ = 29.0, maxZ = 31.0,
distance = 2.5,
}
},
inventory = {
{ name = 'WEAPON_M4A1_CUSTOM', price = 5000 },
{ name = 'ammo-rifle', price = 50, count = 100 },
{ name = 'ammo-pistol', price = 30, count = 100 },
},
},
['ammo_shop'] = {
name = 'Negozio Munizioni',
blip = { id = 110, colour = 2, scale = 0.7 },
targets = {
{
loc = vec3(150.0, -200.0, 25.0),
length = 1.5, width = 1.5, heading = 0,
minZ = 24.0, maxZ = 26.0,
distance = 2.5,
}
},
inventory = {
{ name = 'ammo-rifle', price = 60, count = 100 },
{ name = 'ammo-pistol', price = 40, count = 100 },
{ name = 'ammo-shotgun', price = 70, count = 100 },
},
},
}NOTE
Il tipo di negozio (la chiave, es.
weapon_shop_basic) è quello che userai per aprirlo. Letargetssostituiscono la vecchialocation: ox_target mostra il negozio come punto interagibile.
Registrare uno shop a runtime
In alternativa ai file, puoi registrare un negozio dal server della tua risorsa con l’export RegisterShop:
-- server.lua
exports.ox_inventory:RegisterShop('weapon_shop_custom', {
name = 'Armeria Custom',
targets = {
{ loc = vec3(250.0, -150.0, 30.0), length = 1.5, width = 1.5, heading = 0, minZ = 29.0, maxZ = 31.0, distance = 2.5 }
},
inventory = {
{ name = 'WEAPON_M4A1_CUSTOM', price = 5000 },
},
})Aprire lo shop
Sul client, per aprire un negozio registrato:
-- client.lua
exports.ox_inventory:openInventory('shop', {
type = 'weapon_shop_basic',
})2. Dare Arma con ESX
Comando Admin
-- server.lua
RegisterCommand('givecustomweapon', function(source, args)
local target = tonumber(args[1]) or source
local xPlayer = ESX.GetPlayerFromId(target)
if xPlayer then
-- ox_inventory gestisce arma + munizioni
xPlayer.addWeapon('WEAPON_M4A1_CUSTOM', 120)
-- Notifica da server con ox_lib (non TriggerClientEvent ox_lib:notify)
exports.ox_lib:notify(source, {
title = 'Arma Ricevuta',
description = 'Hai ricevuto la M4A1 Tactical',
type = 'success'
})
end
end, true)
-- Permessi admin (ACE)
add_ace resource.mia_risorsa command.givecustomweapon allowWARNING
Per notificare da server usa
exports.ox_lib:notify(source, {...}).TriggerClientEvent('ox_lib:notify', ...)non funziona:lib.notifyesiste solo sul client.
Acquisto con Denaro (validazione lato server)
-- server.lua
RegisterNetEvent('myresource:buyWeapon')
AddEventHandler('myresource:buyWeapon', function()
local xPlayer = ESX.GetPlayerFromId(source)
local price = Config.WeaponPrice or 5000
-- Mai fidarsi del client: prezzo calcolato qui, non arrivato dal client
if xPlayer.getAccount('money').money >= price then
xPlayer.removeAccountMoney('money', price)
xPlayer.addWeapon('WEAPON_M4A1_CUSTOM', 120)
exports.ox_lib:notify(source, {
title = 'Acquisto Riuscito',
description = 'Hai acquistato la M4A1 Tactical per ' .. price .. '$',
type = 'success'
})
else
exports.ox_lib:notify(source, {
title = 'Saldo Insufficiente',
description = 'Ti servono ' .. price .. '$',
type = 'error'
})
end
end)Con ox_target (punto vendita)
-- client.lua
CreateThread(function()
exports.ox_target:addBoxZone({
coords = vector3(250.0, -150.0, 29.5),
size = vec3(1.5, 1.5, 2.0),
rotation = 0,
debug = Config.Debug,
options = {
{
name = 'buy_custom_weapon',
icon = 'fa-solid fa-gun',
label = 'Compra M4A1 Tactical',
onSelect = function()
exports.ox_inventory:openInventory('shop', { type = 'weapon_shop_basic' })
end,
canInteract = function()
return true
end
}
}
})
end)3. Crafting con ox_inventory
Il crafting nativo si definisce in ox_inventory/data/crafting.lua con ricette raggruppate. Il formato reale usa ingredients (tabella nome → quantità), duration, count e points/zones.
Configurazione
-- ox_inventory/data/crafting.lua
return {
{
name = 'crafting_workbench', -- nome del gruppo ricette
items = {
{
name = 'ammo-rifle', -- item che si crea
ingredients = {
gunpowder = 2,
scrapmetal = 5,
},
duration = 5000, -- 5 secondi
count = 30, -- quanti se ne ottengono
},
{
name = 'WEAPON_M4A1_CUSTOM',
ingredients = {
scrapmetal = 20,
gunpowder = 5,
plastic = 10,
electronic_parts = 3,
},
duration = 15000, -- 15 secondi
count = 1,
},
},
points = { -- punti di crafting (distanza di interazione)
vec3(300.0, -100.0, 29.5),
},
-- In alternativa: zones = { { coords = vec3(...), size = vec3(...), distance = 1.5, rotation = 0 } },
blip = { id = 566, colour = 31, scale = 0.8 },
},
}Aprire il banco da lavoro
-- client.lua
CreateThread(function()
exports.ox_target:addBoxZone({
coords = vector3(300.0, -100.0, 29.5),
size = vec3(2.0, 2.0, 2.0),
rotation = 0,
debug = Config.Debug,
options = {
{
name = 'open_crafting',
label = 'Apri Banco da Lavoro',
icon = 'fa-solid fa-screwdriver-wrench',
onSelect = function()
exports.ox_inventory:openInventory('craft', {
name = 'crafting_workbench',
})
end
}
}
})
end)4. Rimozione Arma alla Morte
INFO
ox_inventory gestisce automaticamente la perdita armi alla morte se configurato. Puoi personalizzare il comportamento ascoltando gli eventi
ox_inventory:
-- server.lua
-- Impedisci la perdita di armi custom alla morte
AddEventHandler('ox_inventory:dropItem', function(inv, item, count, metadata)
if item.name == 'WEAPON_M4A1_CUSTOM' then
return false -- Non lasciare cadere
end
end)NOTE
Le firme esatte degli eventi possono cambiare tra versioni: verifica i nomi nella versione installata o nella documentazione ufficiale prima di affidarti a questi handler in produzione.
TIP
Prossimo passo: 04 - Veicoli Custom con ESX
5. Armi Melee con ESX
NOTE
Le armi melee seguono le stesse regole delle armi da fuoco per quanto riguarda l’integrazione ESX, ma con alcune differenze importanti: non usano munizioni, ammo è sempre 1, e non hanno componenti. Per la guida completa, vedi Armi Melee (Spade).
Registrazione Item
-- ox_inventory/data/weapons.lua
Weapons = {
['WEAPON_LONGSWORD'] = {
label = 'Longsword',
weight = 1500,
durability = 0.1,
-- nessun ammoname: e' melee
},
}Dare con ESX (nessuna munizione)
-- Le melee non hanno munizioni — il secondo parametro e' ignorato
xPlayer.addWeapon('WEAPON_LONGSWORD', 1)Torna alla: Indice Generale