Dokumentation

Dokumentation Clothing store

Ein Kleidungsladen mit gespeicherten Outfits, Firmen-Garderoben und einem Editor, der den Katalog direkt im Spiel bepreist. Jede Komponente und jedes Prop, Stück für Stück gekauft oder als ganzer Look, mit einem serverseitigen Register, das verhindert, dass jemand etwas trägt, wofür er nie bezahlt hat.

  • ESX
  • QBCore
  • vRP
  • Standalone
  • oxmysql
01

Installation

  1. Resource ablegen

    Hol dir das Script aus deinem Tebex-Konto, kopier den Ordner avenida_clotheshops/ in dein resources-Verzeichnis und füg ensure avenida_clotheshops hinter ensure oxmysql in deine Serverconfig ein.

  2. SQL ausführen

    Führ Abschnitt [A] von INSTALL.sql auf deiner Datenbank aus. Abschnitt [B] ist bedingt, der Dateikopf sagt, wann du ihn brauchst.

  3. Admin-Rechte vergeben

    Füg add_ace group.admin avenida_clotheshops.admin allow und add_ace group.admin avenida_clotheshops.vip allow in deine Serverconfig ein. Das erste öffnet den Katalog-Editor, das zweite schaltet frei, was du hinter die VIP-Liste legst.

  4. Den Katalog direkt im Spiel bepreisen

    Setz Config.DevMode.Enabled = true, geh in einen Laden und öffne den Editor. Leg Preise fest, blende aus, was du nicht verkaufst, und reservier für einen Job, was dorthin gehört. Alles landet in config/clothes_overrides.lua. Schalt DevMode danach wieder aus, jede Speicherung wird ohnehin serverseitig erneut geprüft.

  5. Integrationen prüfen

    Setz Config.Debug = true, starte neu und lies die Konsole: Eine Zeile pro Bridge-Kategorie nennt das gewählte Target. Config.Debug steuert nur das Logging und ist nicht der Schalter für den Editor.

02

Konfiguration

Eine Sektion auf drei Arten bepreisen

Jeder Laden deklariert seine Sektionen, und jede Sektion ihren Preismodus. Ein fester Satz für eine ganze Sektion, ein Multiplikator, der spätere Drawables teurer macht, oder eine Tabelle, wenn nur eine Handvoll Teile einen eigenen Preis verdienen.

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()

    Das Outfit, das der Spieler trägt, Komponente für Komponente, samt Props. Genau das schreibt der Shop beim Kauf, es deckt sich also immer mit dem, was die Garderobe zeigt.

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

    Wendet ein komplettes Aussehen auf einen Ped an. Ein Outfit leert den Decoration-Slot, deshalb trägt dieser Aufruf danach die Arbeit von Barber und Tattoo wieder ein, statt blanke Haut zurückzulassen.

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

    Wechselt die Kleidung und sonst nichts. Mit temporary auf true gilt das Outfit nur für die Session, genau so soll sich eine Uniform verhalten, die ein Job ausgibt.

Server

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

    Die Kapazität, die ein Rucksack-Drawable mitbringt, Gewicht und Slots, oder nil, wenn das Drawable nichts fasst. Ruf den Export aus deiner Inventory-Resource auf, damit ein gekaufter Rucksack wirklich etwas fasst.

04

Rezepte

Einen Laden mit eigener Steuer und eigenem Rabatt eröffnen

Ein Laden ist ein Eintrag. Er trägt seinen Anzeigenamen, seine Zahlungsart, sein Währungssymbol, eine optionale Steuer und einen Rabatt auf die Warenkorbsumme und die Sektionen, die er anbietet. Halt den Key stabil: Er ist die Laden-Id, die in Outfits gespeichert wird, und wer ihn umbenennt, nachdem Spieler dort eingekauft haben, zerschießt ihre Daten.

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

Eine Uniform einem Job vorbehalten

Ein eingeschränktes Teil ist für alle unsichtbar, die die Prüfung nicht bestehen, ein Zivilist sieht die Polizeijacke also nie im Raster. Firmen-Garderoben gehen weiter: Der Chef pflegt eine gemeinsame Liste, und jedes Mitglied trägt sie, ohne zu zahlen, genau das, was ein Rekrut in seiner ersten Schicht braucht.

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
}

Das Besitz-Register abschalten

Es ist standardmäßig an und hält einen manipulierten Client davon ab, den Katalog gratis zu tragen. Schalt es nur ab, wenn eine andere deiner Resources Spieler in Teile kleidet, die sie nie gekauft haben, und du das Register dafür nicht befüllen willst. Für bestehende Charaktere wird das Register aus dem befüllt, was sie ohnehin tragen, ein späteres Einschalten nimmt also nichts weg.

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

Decorations aus deinem eigenen Script neu zeichnen

Ein komplettes Outfit leert den Decoration-Slot des Peds, den sich jede Resource auf dem Server teilt. Wenn dein Script einen Spieler einkleidet, lies vorher aus, was diese Resource besitzt, und gib es danach zurück, sonst gehen Tattoos und Hair Base mit der Änderung verloren.

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

Fragen

Ein Spieler sagt, er habe Kleidung verloren, die ihm gehörte

Prüf Config.Clothes.RequireOwnership. Das Register übernimmt beim ersten Mal, was ein Charakter ohnehin trägt, das Einschalten nimmt also niemandem seine Garderobe weg. Was es ablehnt, ist ein Schreibvorgang für ein Teil ohne Kauf dahinter, und genau das schickt ein manipulierter Client. Wenn eine deiner Resources Spieler in nie gekaufte Teile kleidet, registrier diese Käufe oder setz das Flag auf false.

Der Katalog-Editor öffnet nicht

Er braucht beides gleichzeitig: die ACE-Permission avenida_clotheshops.admin und Config.DevMode.Enabled = true. Config.Debug ist ein anderer Schalter und steuert nur das Logging. Jede Speicherung wird serverseitig erneut geprüft, es reicht also nicht, sich die Permission im Spiel selbst zu geben.

Dieselbe Jacke taucht mehrfach auf

Das ist GTA. Das Spiel wiederholt ein Drawable über mehrere Indizes, und die meisten Läden listen jeden einzelnen davon. Phantom-Drawables werden hier gefiltert, wenn du also noch ein Duplikat siehst, ist es meist ein Kleidungs-Pack, das dasselbe Asset zweimal ausliefert. Blende das überzählige Teil im Editor im Spiel aus, es landet in config/clothes_overrides.lua.

Haare gehen durch einen Helm

Der Schnitt wird pro Item deklariert, ein Helm oder eine Maske, die du selbst ergänzt hast, hat also noch keine Regel. Stell ihr Haarverhalten im Katalog-Editor ein, und denk an den Spieler-Override: Wer seine Frisur behalten will, kann das einstellen, und seine Wahl geht dem automatischen Schnitt vor.

Brauchen die Outfit-Bilder etwas Zusätzliches?

Sie brauchen screenshot-basic, und nur dafür. Es ist die einzige optionale Integration aus der Anforderungstabelle, deren Fehlen ein Spieler überhaupt bemerkt: Ohne sie funktionieren gespeicherte Outfits genau gleich, die Liste zeigt aber Namen statt Vorschaubildern.

Welche Frameworks werden wirklich unterstützt?

QBCore, ESX und vRP, dazu ein Standalone-Modus, der gar kein Framework braucht, und ein custom-Zweig in bridges/framework.lua für alles andere. Die Erkennung läuft beim Start und prüft den echten Export. Qbox und ox_core haben keinen eigenen Zweig: Sie laufen über den Standalone- oder Custom-Pfad, nicht über ein getestetes Target.

Kann ich es neben avenida_barber und avenida_tattoo laufen lassen?

Ja, genau dafür sind sie gebaut. Diese hier greift am stärksten ein, weil ein Outfit den Decoration-Slot leert, also trägt sie nach jeder Änderung wieder ein, was den beiden anderen gehört. Was du nicht tun darfst: die einzelnen Resources und das Bundle avenida_skin gleichzeitig laufen lassen. Die Resource erkennt die Überschneidung und meldet das beim Start in der Konsole.

Was kostet es, wenn niemand einkauft?

0.00ms. Die Interaktionspunkte teilen sich einen Thread, der auf eine Sekunde hochgeht, wenn niemand in der Nähe ist, Blips werden einmal erzeugt, und jeder Session-Thread wird beim Verlassen beendet. Der Vorschau-Debounce existiert nur, solange ein Menü offen ist, und lässt sich für schwächere Rechner anpassen.

Warenkorb
Spirit RP
Discord