Veicoli Custom con ESX + ox_inventory

INFO

Integrare un veicolo custom in ESX significa: registrarlo come veicolo acquistabile, gestire le chiavi con ox_inventory, e permettere lo spawn.

ObiettivoDettagli
Cosa imparerai• Registrare veicoli custom in ESX
• Configurare concessionarie e acquisti
• Gestire chiavi veicolo con ox_inventory
• Creare garage con interazione ox_target
Prerequisiti• Un veicolo custom aggiunto al server
• ox_inventory configurato
• Conoscenza base MySQL

1. Registrare il Veicolo in ESX

ESX carica i veicoli da es_extended/shared/vehicles.lua (o shared/vehicles.lua nella tua risorsa se hai un ESX configurato per farlo).

-- shared/vehicles.lua
return {
    -- Veicoli normali
    ['charger20'] = {
        model = 'charger20',           -- modelName dal vehicles.meta
        label = 'Dodge Charger 2020',  -- Nome visibile
        category = 'polizia',           -- Categoria (vedi sotto)
        price = 150000,                -- Prezzo di acquisto
        hash = nil,                    -- Auto-generato dal model name
        shop = 'pdm',                  -- Negozio (pdm = concessionaria)
        stocks = 5,                    -- Disponibilità (-1 = illimitato)
    },
    
    -- Veicoli della polizia
    ['police_charger'] = {
        model = 'police_charger',
        label = 'Charger Polizia',
        category = 'polizia',
        price = 0,                     -- Gratuito (solo per lavoro)
        shop = 'police',
        job = 'police',                -- Solo per job polizia
        stocks = -1,
    },
    
    -- Veicoli da lavoro
    ['work_van'] = {
        model = 'work_van',
        label = 'Furgone da Lavoro',
        category = 'lavoro',
        price = 50000,
        shop = 'pdm',
        stocks = 3,
    }
}

Categorie

Le categorie più comuni:

NomeLabelTipologia
compactsCompatteAuto piccole
sedansBerlineAuto medie
suvsSUVFuoristrada
sportsSportiveAuto veloci
muscleMuscleAuto potenti
motorcyclesMotoDue ruote
poliziaPoliziaVeicoli di servizio
ambulanzaAmbulanzaEMS
lavoroLavoroVeicoli utility
importImportAuto speciali

2. Concessionaria con ox_inventory

ox_inventory può gestire l’acquisto di veicoli.

Shop Veicoli

-- ox_inventory/data/shops.lua
{
    name = 'vehicle_shop_pdm',
    label = 'Concessionaria',
    location = vector3(-45.0, -1100.0, 26.0),
    blip = {
        id = 326, color = 2, scale = 0.8
    },
    inventory = {
        { name = 'charger20', price = 150000, type = 'vehicle' },
        { name = 'sports_car', price = 300000, type = 'vehicle' },
    }
}

Acquisto Veicolo

WARNING

Attenzione alla doppia chiamata a GeneratePlate() — la targa nel campo plate della tabella e quella dentro il JSON vehicle devono coincidere. Usa una variabile per salvare la targa generata.

-- server.lua
RegisterNetEvent('myresource:buyVehicle')
AddEventHandler('myresource:buyVehicle', function(model, price)
    local xPlayer = ESX.GetPlayerFromId(source)
    
    if xPlayer.getAccount('bank').money >= price then
        xPlayer.removeAccountMoney('bank', price)
        
        -- Genera la targa UNA volta e riusala in entrambi i campi
        local plate = GeneratePlate()
        
        -- Salva il veicolo nel database
        MySQL.insert('INSERT INTO owned_vehicles (owner, plate, vehicle) VALUES (?, ?, ?)', {
            xPlayer.identifier,
            plate,
            json.encode({ model = model, plate = plate })
        }, function(insertId)
            TriggerClientEvent('ox_lib:notify', source, {
                title = 'Veicolo Acquistato',
                description = model .. ' acquistato per €' .. price,
                type = 'success'
            })
        end)
    end
end)

3. Chiavi Veicolo con ox_inventory

ox_inventory gestisce le chiavi automaticamente tramite l’item vehiclekey.

-- server.lua
-- Quando un giocatore compra un veicolo, dagli le chiavi
RegisterNetEvent('myresource:giveKeys')
AddEventHandler('myresource:giveKeys', function(plate)
    local xPlayer = ESX.GetPlayerFromId(source)
    
    -- Aggiunge le chiavi come item (ox_inventory le riconosce)
    exports.ox_inventory:AddItem(source, 'vehiclekey', 1, {
        plate = plate,
        model = 'charger20'
    })
end)
 
-- Rimuovi chiavi se il veicolo viene venduto
RegisterNetEvent('myresource:removeKeys')
AddEventHandler('myresource:removeKeys', function(plate)
    local xPlayer = ESX.GetPlayerFromId(source)
    
    -- Rimuovi tutte le chiavi per quella targa
    local items = exports.ox_inventory:GetItems(source, 'vehiclekey')
    for _, item in ipairs(items) do
        if item.metadata.plate == plate then
            exports.ox_inventory:RemoveItem(source, 'vehiclekey', 1, item.metadata)
            break
        end
    end
end)

4. Spawn Veicolo con Garage ESX

Garage con ox_target

-- client.lua
local ESX = exports['es_extended']:getSharedObject()
 
CreateThread(function()
    -- Punto garage
    exports.ox_target:addBoxZone({
        coords = vector3(200.0, -800.0, 30.0),
        size = vec3(3.0, 3.0, 2.0),
        rotation = 0,
        debug = Config.Debug,
        options = {
            {
                name = 'open_garage',
                event = 'myresource:openGarage',
                icon = 'fa-solid fa-warehouse',
                label = 'Apri Garage',
                job = nil  -- Accessibile a tutti
            }
        }
    })
end)
 
-- Apre il garage
RegisterNetEvent('myresource:openGarage')
AddEventHandler('myresource:openGarage', function()
    ESX.TriggerServerCallback('myresource:getVehicles', function(vehicles)
        -- Mostra lista veicoli con ox_lib
        local options = {}
        for _, v in ipairs(vehicles) do
            options[#options + 1] = {
                title = v.model,
                description = 'Targa: ' .. v.plate,
                onSelect = function()
                    TriggerServerEvent('myresource:spawnVehicle', v.plate)
                end
            }
        end
        
        lib.registerContext({
            id = 'garage_menu',
            title = 'Garage',
            options = options
        })
        lib.showContext('garage_menu')
    end)
end)

Server Callback

-- server.lua
ESX.RegisterServerCallback('myresource:getVehicles', function(source, cb)
    local xPlayer = ESX.GetPlayerFromId(source)
    
    MySQL.query('SELECT * FROM owned_vehicles WHERE owner = ?', {
        xPlayer.identifier
    }, function(result)
        local vehicles = {}
        for _, v in ipairs(result) do
            local data = json.decode(v.vehicle)
            vehicles[#vehicles + 1] = {
                model = data.model,
                plate = v.plate
            }
        end
        cb(vehicles)
    end)
end)
 
RegisterNetEvent('myresource:spawnVehicle')
AddEventHandler('myresource:spawnVehicle', function(plate)
    local xPlayer = ESX.GetPlayerFromId(source)
    
    MySQL.query('SELECT * FROM owned_vehicles WHERE plate = ?', {
        plate
    }, function(result)
        if result[1] then
            local vehicleData = json.decode(result[1].vehicle)
            TriggerClientEvent('myresource:spawnVehicleClient', source, vehicleData.model, plate)
        end
    end)
end)

5. Test

TIP

Procedura di test:

  1. Assicurati che il veicolo sia registrato in shared/vehicles.lua
  2. Aggiungi lo shop in ox_inventory/data/shops.lua
  3. Vai alla concessionaria e acquista il veicolo
  4. Vai al garage e spawnalo

TIP

Prossimo passo: 05 - Vestiti e Skin con ESX


Torna alla: Indice Generale