Sistema di crafting FiveM: banchi ox_inventory e crafting personalizzato

Costruisci crafting su FiveM: banchi di crafting di ox_inventory in data/crafting.lua con ingredienti e zone, una ricetta personalizzata controllata dal server, e suggerimenti anti-dupe.

Crafting significa che un giocatore trasforma alcuni oggetti in un altro oggetto. Puoi usare i banchi di crafting incorporati in ox_inventory, o scrivere la tua ricetta in uno script. Questo articolo mostra entrambi, e quindi i controlli che impediscono ai giocatori di duplicare gli oggetti.

Banchi di crafting ox_inventory

Apri ox_inventory/data/crafting.lua. Restituisce un elenco di banchi. Ogni banco ha un elenco di elementi artigianali e un posto nel mondo:

lua
return {
    {
        items = {
            {
                name = 'lockpick',
                ingredients = {
                    scrap_metal = 5,
                    plastic = 2,
                },
                duration = 5000,
                count = 1,
            },
            {
                name = 'bandage',
                ingredients = {
                    cloth = 2,
                },
                duration = 3000,
            },
        },
        points = {
            vec3(1087.3, -3099.4, -39.0),
        },
    },
}

Cosa fa ogni campo:

Campo Significato
name L'oggetto che viene prodotto
ingredients Nomi degli oggetti e il conteggio di ognuno necessario
duration Tempo di crafting in millisecondi
count Quanti del risultato ottieni per craft
points Coordinate dove si può usare il banco
zones Zone di scatola per ox_target, come alternativa a points

Tutto nominato in name o ingredients deve esistere in data/items.lua. Vedi aggiunta di oggetti a ox_inventory. Riavvia ox_inventory dopo aver modificato il file.

Suggerimento: un valore di ingrediente inferiore a 1 non consuma l'oggetto, usa quella frazione della sua durabilità. Un valore di 0.1 su uno strumento con durabilità usa il dieci percento di esso.

Zone invece di punti

Una zona è una scatola che il giocatore può selezionare:

lua
zones = {
    {
        coords = vec3(1087.3, -3099.4, -39.0),
        size = vec3(1.5, 1.0, 1.0),
        distance = 1.5,
        rotation = 45.0,
    },
},

Le zone hanno bisogno che ox_target sia in esecuzione. Guarda gli esempi nella tua copia di data/crafting.lua per i campi esatti della tua versione, poiché il formato cambia tra le versioni. Per limitare un banco a un lavoro, ox_inventory legge anche groups sul banco, la stessa idea di depositi ox_inventory.

Una ricetta personalizzata con controlli del server

Se vuoi le tue regole, come un livello di abilità, un costo o una barra di progresso di tua scelta, scrivi la ricetta nel tuo script e lascia che ox_inventory gestisca solo gli oggetti. La parte importante è che il server fa tutto:

lua
-- server.lua
local crafting = {}

local recipe = {
    result = 'lockpick',
    ingredients = { scrap_metal = 5, plastic = 2 },
}

lib.callback.register('my_script:craft', function(source)
    if crafting[source] then return false end
    crafting[source] = true

    local ok = false

    -- 1. check every ingredient
    local hasAll = true
    for item, count in pairs(recipe.ingredients) do
        if exports.ox_inventory:Search(source, 'count', item) < count then
            hasAll = false
            break
        end
    end

    -- 2. check the player can carry the result
    if hasAll and exports.ox_inventory:CanCarryItem(source, recipe.result, 1) then
        -- 3. remove, then add
        local removed = {}
        local allRemoved = true
        for item, count in pairs(recipe.ingredients) do
            if exports.ox_inventory:RemoveItem(source, item, count) then
                removed[item] = count
            else
                allRemoved = false
                break
            end
        end

        if allRemoved and exports.ox_inventory:AddItem(source, recipe.result, 1) then
            ok = true
        else
            -- give back what was removed
            for item, count in pairs(removed) do
                exports.ox_inventory:AddItem(source, item, count)
            end
        end
    end

    crafting[source] = nil
    return ok
end)

Il client chiede, riproduce la barra di progresso, e legge solo la risposta:

lua
-- client.lua
if lib.progressBar({ duration = 5000, label = 'Crafting' }) then
    local ok = lib.callback.await('my_script:craft', false)
    lib.notify({ description = ok and 'Crafted' or 'Missing items', type = ok and 'success' or 'error' })
end

Per le funzioni di callback e notifica, vedi callback del server su ESX, QBCore e ox_lib.

Suggerimenti anti-dupe

Il crafting è un posto classico per la duplicazione di elementi, perché gli oggetti vengono rimossi e aggiunti in due passaggi. Mantieni queste regole:

  • Solo server. Il server controlla gli ingredienti e dà il risultato. Il client invia "Voglio fare la ricetta X", mai conteggi o nomi di elementi che ha inventato.
  • Controlla, quindi rimuovi, quindi aggiungi. Non aggiungere mai il risultato prima che la rimozione fosse riuscita. Se l'aggiunta fallisce, restituisci gli ingredienti.
  • Un craft alla volta. Un flag per giocatore, come crafting[source] sopra, impedisce a un evento lanciato di eseguire la ricetta più volte in parallelo.
  • Controlla CanCarryItem prima. Un inventario pieno è il solito motivo per cui AddItem fallisce, e il giocatore perderebbe gli ingredienti.
  • Controlla la distanza. Se la ricetta appartiene a un banco, confronta le coordinate del giocatore al banco sul server.
  • Cancella lo stato su drop. Ripristina il flag quando un giocatore se ne va, così una disconnessione nel mezzo non blocca la ricetta.
lua
AddEventHandler('playerDropped', function()
    crafting[source] = nil
end)

Per altri modi di proteggere gli eventi, vedi protezione degli eventi del server.

Checklist

Sintomo Soluzione
Il banco non appare Modifica data/crafting.lua, quindi riavvia ox_inventory
Errori di ricetta all'avvio Un oggetto in name o ingredients manca da data/items.lua
La zona non fa nulla ox_target deve essere in esecuzione e i campi della zona devono corrispondere alla tua versione
Ingredienti persi, nessun risultato Controlla CanCarryItem prima e rimborsa quando AddItem fallisce
Oggetti duplicati Sposta l'intera ricetta al server, aggiungi un flag uno alla volta
Il craft funziona da lontano Controlla la distanza del giocatore dal banco sul server

Risposte rapide

Come aggiungo un banco di crafting a ox_inventory?

Aggiungi una voce a ox_inventory/data/crafting.lua con items (ognuno con ingredients e duration) e o points o zones per dove si trova il banco. Riavvia ox_inventory.

Una ricetta può usare parte della durabilità di un oggetto?

Sì. Un valore di ingrediente inferiore a 1 usa quella frazione della durabilità di un oggetto che lo ha, piuttosto che consumare l'oggetto.

Come impedisco ai giocatori di duplicare elementi durante il crafting?

Fai l'intera ricetta sul server: controlla gli ingredienti, rimuovili, quindi aggiungi il risultato, e rifiuta di iniziare un secondo craft mentre uno è in esecuzione per quel giocatore.

Script senza questo problema

Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →Quest CreatorUn editor visuale di missioni e dialoghi con gli NPC, costruito nodo per nodo in gioco.Vedi script →

Continua a leggere