Système de craft FiveM : bancs ox_inventory et craft personnalisé

Construire du craft sur FiveM : bancs de craft ox_inventory dans data/crafting.lua avec des ingrédients et des zones, une recette personnalisée vérifiée par le serveur, et conseils anti-dupe.

Le craft signifie qu'un joueur transforme certains articles en un autre article. Vous pouvez utiliser les bancs de craft intégrés à ox_inventory, ou écrire votre propre recette dans un script. Cet article montre les deux, puis les vérifications qui empêchent les joueurs de dupliquer des articles.

Bancs de craft ox_inventory

Ouvrez ox_inventory/data/crafting.lua. Il retourne une liste de bancs. Chaque banc a une liste d'articles craftables et un endroit dans le monde :

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),
        },
    },
}

Ce que chaque champ fait :

Champ Signification
name L'article produit
ingredients Noms d'articles et le nombre de chacun nécessaire
duration Temps de craft en millisecondes
count Combien du résultat vous obtenez par craft
points Coordonnées où le banc peut être utilisé
zones Zones de boîtes pour ox_target, comme alternative à points

Tout ce qui est nommé dans name ou ingredients doit exister dans data/items.lua. Voir ajouter des articles à ox_inventory. Redémarrez ox_inventory après édition du fichier.

Astuce : une valeur d'ingrédient inférieure à 1 ne consomme pas l'article, elle utilise cette fraction de sa durabilité. Une valeur de 0.1 sur un outil avec durabilité utilise dix pour cent de celle-ci.

Zones au lieu de points

Une zone est une boîte que le joueur peut cibler :

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

Les zones ont besoin que ox_target soit en cours d'exécution. Regardez les exemples dans votre copie de data/crafting.lua pour les champs exacts de votre version, car le format change entre les versions. Pour restreindre un banc à un emploi, ox_inventory lit aussi groups sur le banc, la même idée que dans coffres ox_inventory.

Une recette personnalisée avec vérifications serveur

Si vous voulez vos propres règles, telles qu'un niveau de compétence, un coût ou une barre de progression de votre choix, écrivez la recette dans votre script et laissez ox_inventory gérer seulement les articles. La partie importante est que le serveur fait tout :

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)

Le client demande, joue la barre de progression, et lit seulement la réponse :

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

Pour les fonctions de rappel et de notification, voir rappels serveur sur ESX, QBCore et ox_lib.

Conseils anti-dupe

Le craft est un endroit classique pour la duplication d'articles, car les articles sont enlevés et ajoutés en deux étapes. Gardez ces règles :

  • Serveur seulement. Le serveur vérifie les ingrédients et donne le résultat. Le client envoie « Je veux crafter la recette X », jamais les comptes ou les noms d'articles qu'il a inventés.
  • Vérifier, puis enlever, puis ajouter. N'ajoutez jamais le résultat avant que l'enlèvement réussisse. Si l'ajout échoue, redonnez les ingrédients.
  • Un craft à la fois. Un drapeau par joueur, comme crafting[source] ci-dessus, empêche un événement spammé de exécuter la recette plusieurs fois en parallèle.
  • Vérifiez CanCarryItem d'abord. Un inventaire plein est la raison habituelle pour laquelle AddItem échoue, et le joueur perdrait les ingrédients.
  • Vérifiez la distance. Si la recette appartient à un banc, comparez les coordonnées du joueur à celles du banc sur le serveur.
  • Videz l'état à la suppression. Réinitialisez le drapeau quand un joueur part, pour qu'une déconnexion au milieu ne verrouille pas la recette.
lua
AddEventHandler('playerDropped', function()
    crafting[source] = nil
end)

Pour plus sur la protection des événements, voir Sécuriser les événements serveur.

Liste de vérification

Symptôme Correction
Le banc n'apparaît pas Modifiez data/crafting.lua, puis redémarrez ox_inventory
Erreurs de recette au démarrage Un article dans name ou ingredients manque dans data/items.lua
La zone ne fait rien ox_target doit s'exécuter, et les champs de zone doivent correspondre à votre version
Ingrédients perdus, pas de résultat Vérifiez CanCarryItem d'abord et remboursez quand AddItem échoue
Articles dupliqués Déplacez la recette entière au serveur, ajoutez un drapeau une-à-la-fois
Le craft fonctionne de loin Vérifiez la distance du joueur au banc sur le serveur

Réponses rapides

Comment ajouter un banc de craft à ox_inventory ?

Ajoutez une entrée à ox_inventory/data/crafting.lua avec items (chacun avec ingredients et duration) et soit points soit zones pour l'endroit où le banc se tient. Redémarrez ox_inventory.

Une recette peut-elle utiliser une partie de la durabilité d'un article ?

Oui. Une valeur d'ingrédient inférieure à 1 utilise cette fraction de la durabilité d'un article qui la possède, plutôt que de consommer l'article.

Comment empêcher les joueurs de dupliquer des articles pendant le craft ?

Faites la recette entière sur le serveur : vérifiez les ingrédients, enlevez-les, puis ajoutez le résultat, et refusez de commencer un deuxième craft pendant qu'un s'exécute pour ce joueur.

Des scripts sans ce problème

Item Creator V2Créez des items utilisables avec animations, props, effets et plus — sans écrire une ligne de code.Voir le script →Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →Quest CreatorUn éditeur visuel de quêtes et de dialogues PNJ, construit nœud par nœud en jeu.Voir le script →

À lire aussi