Documentation

Documentation Clothing store

Un magasin de vêtements avec tenues sauvegardées, garde-robes d'entreprise et un éditeur qui tarife le catalogue depuis le jeu. Tous les composants et tous les props, achetés pièce par pièce ou en tenue complète, avec un registre côté serveur qui empêche de porter ce qu'on n'a jamais payé.

  • ESX
  • QBCore
  • vRP
  • Standalone
  • oxmysql
01

Installation

  1. Déposez la ressource

    Récupérez le script depuis votre compte Tebex, copiez le dossier avenida_clotheshops/ dans votre dossier resources et ajoutez ensure avenida_clotheshops à votre config serveur, après ensure oxmysql.

  2. Passez le SQL

    Exécutez la section [A] d'INSTALL.sql sur votre base. La section [B] est conditionnelle, l'en-tête du fichier dit quand elle s'applique.

  3. Donnez-vous les permissions

    Ajoutez add_ace group.admin avenida_clotheshops.admin allow et add_ace group.admin avenida_clotheshops.vip allow à votre config serveur. La première ouvre l'éditeur de catalogue, la seconde débloque ce que vous placez derrière la liste VIP.

  4. Tarifez le catalogue depuis le jeu

    Mettez Config.DevMode.Enabled = true, entrez dans un magasin et ouvrez l'éditeur. Fixez les prix, masquez ce que vous ne vendez pas, réservez ce qui appartient à un job. Tout atterrit dans config/clothes_overrides.lua. Recoupez DevMode une fois terminé, il est revérifié côté serveur à chaque sauvegarde.

  5. Contrôlez les intégrations

    Mettez Config.Debug = true, redémarrez, et lisez la console : une ligne par catégorie de bridge nomme la cible retenue. Config.Debug ne pilote que les logs, ce n'est pas l'interrupteur de l'éditeur.

02

Configuration

Tarifer une section de trois façons

Chaque magasin déclare ses sections, et chaque section son mode de tarification. Un forfait pour toute une section, un multiplicateur qui rend les drawables suivants plus chers, ou une table quand seules quelques pièces méritent leur propre prix.

lua
-- config/clothes_shops.lua
categories = {
    tops = {
        enabled = true,
        price   = { mode = 'fixed', base = 300 },
    },
    pants = {
        enabled = true,
        -- price = base + index * mult
        price   = { mode = 'multiplier', base = 100, mult = 2 },
    },
    mask = {
        enabled = true,
        price   = { mode = 'table', map = { [12] = 900, [45] = 1500 } },
        -- only these drawables are offered
        whitelist = { 12, 45, 51 },
    },
}
03

Exports

Client

  • GetSkinData
    exports['avenida_clotheshops']:GetSkinData()

    La tenue portée par le joueur, composant par composant, props compris. C'est ce que la boutique écrit à l'achat, donc c'est toujours en phase avec ce que la penderie affiche.

  • ApplySkin
    exports['avenida_clotheshops']:ApplySkin(data, ped)

    Applique une apparence complète à un ped. Poser une tenue vide l'emplacement de décoration, donc cet appel remet ensuite le travail du barbier et du tatoueur au lieu de laisser une peau nue.

  • ApplyClothing
    exports['avenida_clotheshops']:ApplyClothing(data, ped, temporary)

    Change les vêtements et rien d'autre. Avec temporary à true, la tenue ne vit que le temps de la session, ce qui est le comportement attendu d'un uniforme distribué par un métier.

Server

  • GetBagStorage
    exports['avenida_clotheshops']:GetBagStorage(sex, drawable) --> { weight, slots } | nil

    La capacité qu'accorde un drawable de sac, poids et emplacements, ou nil quand ce drawable ne porte rien. Appelez-la depuis votre ressource d'inventaire pour qu'un sac acheté en boutique contienne vraiment quelque chose.

04

Recettes

Ouvrir un magasin avec sa taxe et sa remise

Un magasin est une entrée. Il porte son nom d'affichage, son moyen de paiement, son symbole monétaire, une taxe et une remise appliquées au total du panier, et les sections qu'il propose. Gardez la clé stable : c'est l'identifiant de magasin enregistré dans les tenues, et le renommer après que des joueurs y ont acheté casse leurs données.

lua
-- config/clothes_shops.lua
Config.Clothes.Shops[22] = {
    name       = 'Ponsonbys - Rockford Hills',
    payment    = 'bank',
    currency   = '$',
    tax        = 0.20,        -- +20% on the cart
    discount   = 0.00,
    outfitMode = true,
    blip = { sprite = 73, color = 4, scale = 0.7, coords = vec3(-708.2, -152.2, 37.4) },
    categories = {
        tops  = { enabled = true, price = { mode = 'fixed', base = 900 } },
        shoes = { enabled = true, price = { mode = 'fixed', base = 450 } },
    },
}

Réserver un uniforme à un job

Une pièce restreinte est masquée à qui ne passe pas le contrôle, un civil ne voit donc jamais la veste de police dans la grille. Les garde-robes d'entreprise vont plus loin : le patron édite une liste partagée et chaque membre la porte sans payer, ce qu'il vous faut pour une recrue à sa première prise de service.

lua
-- config/clothes_overrides.lua, or write it from the in-game editor
Overrides['tops'] = {
    [56] = { job = 'police', label = 'LSPD jacket' },
    [12] = { hidden = true },
    [31] = { restricted = true },   -- ACE permission
}

Couper le registre de propriété

Il est actif par défaut et c'est lui qui empêche un client trafiqué de porter le catalogue gratuitement. Ne le coupez que si une autre de vos ressources habille les joueurs avec des pièces qu'ils n'ont jamais achetées et que vous préférez ne pas les initialiser. Les personnages existants sont initialisés depuis ce qu'ils portent, l'activer plus tard ne retire donc rien.

lua
-- config/clothes.lua
Config.Clothes.RequireOwnership = false

-- how far from a store the server still accepts a purchase
Config.Clothes.PurchaseRange = 30.0

-- saved outfits per character, enforced server side
Config.Clothes.MaxOutfits = 30
Config.Clothes.MaxOutfitsRestricted = 50

Redessiner les décorations depuis votre script

Appliquer une tenue complète efface l'emplacement de décorations du ped, partagé par tout le serveur. Si votre script habille un joueur, lisez d'abord ce que cette ressource possède et remettez-le ensuite, sinon les tatouages et la hair base partent avec le changement.

lua
local hairbase = exports['avenida_clotheshops']:GetHairbase()
local tattoos  = exports['avenida_clotheshops']:GetTattoos()

-- your own clothing work here

if hairbase then
    AddPedDecorationFromHashes(PlayerPedId(), hairbase.c, hairbase.t)
end
for _, dec in ipairs(tattoos) do
    AddPedDecorationFromHashes(PlayerPedId(), dec.c, dec.t)
end
05

Questions

Un joueur dit avoir perdu des vêtements qu'il possédait

Regardez Config.Clothes.RequireOwnership. Le registre initialise un personnage depuis ce qu'il porte déjà la première fois qu'il le voit, l'activer ne retire donc pas de garde-robe. Ce qu'il refuse, c'est une écriture pour un vêtement sans achat derrière, ce qu'envoie justement un client trafiqué. Si une de vos ressources habille les joueurs avec des pièces jamais achetées, enregistrez ces achats ou passez le drapeau à false.

L'éditeur de catalogue ne s'ouvre pas

Il lui faut deux choses en même temps : la permission ACE avenida_clotheshops.admin et Config.DevMode.Enabled = true. Config.Debug est un autre interrupteur, il ne pilote que les logs. Chaque sauvegarde est revérifiée côté serveur, se donner la permission en jeu ne suffit donc pas à lui seul.

La même veste apparaît plusieurs fois

C'est GTA. Le jeu répète un drawable sur plusieurs index, et la plupart des magasins les listent tous. Les drawables fantômes sont filtrés ici, donc si vous voyez encore un doublon, c'est en général un pack de vêtements qui livre deux fois le même asset. Masquez celui de trop depuis l'éditeur en jeu, il atterrit dans config/clothes_overrides.lua.

Les cheveux traversent un casque

La coupe est déclarée par item, un casque ou un masque que vous avez ajouté vous-même n'a donc pas encore de règle. Réglez son comportement capillaire depuis l'éditeur de catalogue, et n'oubliez pas la préférence joueur : qui tient à garder sa coiffure peut le dire, et son choix l'emporte sur la coupe automatique.

Les photos de tenues demandent-elles quelque chose ?

Elles demandent screenshot-basic, et uniquement pour ça. C'est la seule intégration optionnelle du tableau des prérequis dont l'absence se voit côté joueur : sans elle, les tenues sauvegardées fonctionnent exactement pareil mais la liste affiche des noms au lieu d'aperçus.

Quels frameworks sont réellement supportés ?

QBCore, ESX et vRP, plus un mode standalone qui ne demande aucun framework et une branche custom dans bridges/framework.lua pour le reste. La détection tourne au démarrage et sonde l'export réel. Qbox et ox_core n'ont pas de branche dédiée : ils passent par le chemin standalone ou custom, pas par une cible testée.

Puis-je le faire tourner à côté de avenida_barber et avenida_tattoo ?

Oui, c'est exactement pour ça qu'ils sont construits. Celui-ci est le plus perturbateur des trois, puisque appliquer une tenue efface l'emplacement de décorations, il remet donc ce que possèdent les deux autres après chaque changement. Ce qu'il ne faut pas faire, c'est lancer les ressources séparées et le pack avenida_skin en même temps. La ressource détecte le recouvrement et le signale en console au démarrage.

Combien ça coûte quand personne ne fait de shopping ?

0.00ms. Les points d'interaction partagent un thread qui se met à une seconde quand personne n'est à proximité, les blips sont créés une fois, et chaque thread de session est tué à la sortie. Le debounce d'aperçu n'existe que pendant qu'un menu est ouvert, et il se règle pour les machines faibles.

Panier
Spirit RP
Discord