Dokumentation

Dokumentation Tattoo shop

Der komplette Tattoo-Katalog des Spiels, mit Warenkorb und einem Stuhl, in den du dich wirklich setzt. 1615 Motive aus 26 DLC-Collections, live an deinem Charakter zu sehen, während du sie hinzufügst, in einem Rutsch bezahlt. Laser-Entfernung inklusive, und ein Artist, der hereinkommt und die Arbeit erledigt.

  • ESX
  • QBCore
  • vRP
  • Standalone
  • oxmysql
01

Installation

  1. Resource ablegen

    Hol dir das Script aus deinem Tebex-Konto, kopier den Ordner avenida_tattoo/ in dein resources-Verzeichnis und füg ensure avenida_tattoo 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. Preise festlegen

    Öffne config/tattoo.lua. Der feste Satz, die Multiplikatoren pro Collection und die Lasergebühr sind die drei Zahlen, die du vor der Eröffnung festlegen solltest. Sprache und Bridges liegen in config/config.lua.

  4. Integrationen prüfen

    Setz Config.Debug = true, starte neu und lies die Konsole: Eine Zeile pro Bridge-Kategorie nennt das gewählte Target. Setz es wieder auf false, sobald die Zeilen zu deinem Server passen. Die freigeschalteten Diagnosebefehle kosten einen Frame-Hitch.

  5. Admin-Rechte geben

    Füg add_ace group.admin avenida_tattoo.admin allow in deine Serverconfig ein und ruf dann im Spiel /avenida_tattoo_check für den vollen Bericht auf.

02

Konfiguration

Den Preis der Tinte festlegen

Ein fester Satz deckt den ganzen Katalog ab, und die Multiplikatoren machen alte Collections billig und seltene teuer, ohne 1615 Motive von Hand zu bepreisen. Alles wird beim Bezahlen serverseitig neu berechnet.

lua
-- config/tattoo.lua
Config.Tattoo.Prices = {
    flat  = 1000,   -- every tattoo, unless PricePerZone is on
    hair  = 500,
    reset = 3000,   -- laser removal, per tattoo removed
}

Config.Tattoo.PricePerZone = false

Config.Tattoo.CollectionMultipliers = {
    multiplayer_overlays = 0.80,   -- base game, cheaper
    mpHipster_overlays   = 0.85,
    mpBeach_overlays     = 0.85,
    -- anything not listed stays at 1.0
}
03

Exports

Client

  • GetHairbase
    exports['avenida_tattoo']:GetHairbase() --> { c = collection, t = nameHash } | nil

    Die Hairbase, die der Ped gerade trägt. Das Ink-Studio besitzt sie nicht, muss sie aber nach jedem Redraw zurückgeben, und jede Resource von dir, die Decorations löscht, muss das genauso tun.

  • GetTattoos
    exports['avenida_tattoo']:GetTattoos() --> { { c, t }, ... }

    Die vollständige Liste der getragenen Tattoos als Paare aus Collection und Name-Hash. Das ist die maßgebliche Kopie: Der Laser streicht Einträge daraus, ein Kauf legt neue dazu, lies sie also aus, statt selbst zu cachen.

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

    Der gespeicherte Charakter samt der Zonen-Korrekturen, die die Tinte auf Torso, Armen und Beinen richtig platzieren. Nützlich, wenn dein Script wissen muss, auf welchem Körper es zeichnet.

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

    Überträgt ein Aussehen auf einen Ped, Tattoos inklusive. Der Decoration-Slot wird in einem Durchgang neu aufgebaut. Das vermeidet das Flackern, das entsteht, wenn die Tinte Stück für Stück gesetzt wird.

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

    Zieht einen Ped an, ohne die Tinte anzufassen. Das dritte Argument hält die Änderung aus der Datenbank heraus, genau richtig für eine Szene, die endet, wenn der Spieler weggeht.

04

Rezepte

Nach Körperzone abrechnen statt pauschal

Ist PricePerZone aktiv, rechnet der Server nach der GTA-Decoration-Zone jedes Motivs ab. Achte auf den in der Config dokumentierten Haken: Nur Tattoos, die in einer deklarierten Zone landen, werden verkauft, alles Unkorrigierte verschwindet also aus dem Shop, statt zum falschen Preis verkauft zu werden.

lua
-- config/tattoo.lua
Config.Tattoo.PricePerZone = true

Config.Tattoo.Prices = {
    [0] = 1250, -- torso / back
    [1] = 1000, -- head
    [2] = 600,  -- left arm
    [3] = 600,  -- right arm
    [4] = 750,  -- left leg
    [5] = 750,  -- right leg
    [6] = 750,  -- unknown
    reset = 3000,
}

Ein Tattoo in den richtigen Tab verschieben

GTA legt viele DLC-Motive in der falschen Zone ab. 368 sind bereits korrigiert, und die Liste ist offen, damit du deine eigenen ergänzen kannst. Schalt Config.Debug ein, um im Spiel einen nameHash abzulesen, und trag ihn ein.

lua
-- config/tattoo.lua
Config.Tattoo.SubZoneOverrides = {
    ['FM_Hip_M_Tat_000'] = 'back',
    ['MP_Buis_M_Tat_021'] = 'neck',
    -- 'back' | 'chest' | 'neck' | 'head'
}

Die Sitzung selbst in Szene setzen

Die Szenenkamera wird am Spieler gemessen, in seinen eigenen Achsen, nicht am Stuhl-Prop. Das ist Absicht: Die Sitzfläche liegt selten im Prop-Ursprung, und die Abweichung beträgt von Stuhl zu Stuhl mehrere Meter, weshalb eine stuhlrelative Kamera den Spieler von hinten filmt.

lua
-- config/tattoo.lua
Config.Tattoo.ApplyScene = true

Config.Tattoo.SceneCamera = {
    Enabled      = true,
    Distance     = 1.5,   -- metres in front of the player
    Height       = 0.75,  -- metres above their feet
    TargetHeight = 0.6,   -- aim at chest height
    Fov          = 42.0,
}

Decorations aus deinem eigenen Script neu zeichnen

Der Ped hat einen einzigen Decoration-Slot für den ganzen Server. Wenn dein Script ClearPedDecorations aufruft, lies vorher aus, was diese Resource besitzt, und gib es danach zurück, sonst löschst du jedes Tattoo, für das der Spieler bezahlt hat.

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

ClearPedDecorations(PlayerPedId())
-- your own decoration 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

Warum fehlen manche Tattoos im Shop?

Zwei Gründe, beide gewollt. Neuere DLC-Collections werden nach Game Build eingemischt, ein Motiv, das dein Client nicht rendern kann, wird also gar nicht erst gelistet, statt gelistet und kaputt zu sein. Und mit aktivem PricePerZone werden nur Tattoos verkauft, die in einer deklarierten Zone landen, was in der Config auch so steht: Der größte Teil des Katalogs verschwindet, bis du die Overrides gefüllt hast. Im Standard, also mit ausgeschaltetem PricePerZone, steht der ganze Katalog zum Verkauf.

Ein Tattoo taucht im falschen Tab auf

Das ist GTA, nicht das Script: Das Spiel führt einen großen Teil der DLC-Motive unter einer Zone, die nicht zu der Stelle passt, an der sie am Körper landen. 368 sind bereits von Hand korrigiert, 310 auf den Rücken und 58 an den Hals. Für den Rest schalt Config.Debug ein, lies den nameHash im Spiel ab und ergänz eine Zeile in Config.Tattoo.SubZoneOverrides. Die Datei ist escrow-frei.

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.

Funktioniert es mit dem ox-Stack?

Ja, überall, wo es zählt: ox_lib für Notifications über Config.UseOxLib, ox_target für den Interaktions-Prompt, ox_inventory für Items und oxmysql als einzige harte Dependency. Nichts davon ist Pflicht außer oxmysql. Keinen eigenen Zweig hat ox_core als Framework: Auf einem ox_core-Server läuft die Resource standalone oder über den custom-Zweig von bridges/framework.lua.

Was kostet mich vRP?

vRP speichert Kleidungskomponenten und Props, sonst nichts. Es hat kein Feld für Ped-Decorations, Tattoos haben dort also keinen Platz. Auf vRP hält diese Resource den ganzen Charakter stattdessen in ihrer eigenen Tabelle. Praktische Folge: Ein vRP-eigener Skinshop zeigt die Tinte nicht. vRP 2 und vRP 0.5 werden nicht unterstützt, und die Resource sagt das in der Konsole, statt sich still falsch zu verhalten.

Kann ich es neben avenida_barber und avenida_clotheshops laufen lassen?

Ja, genau dafür sind sie gebaut. Jede besitzt ihre Hälfte des einen Ped-Decoration-Slots und trägt die anderen nach jedem Redraw wieder ein. Was du nicht tun darfst: die einzelnen Resources und das Bundle avenida_skin gleichzeitig laufen lassen. Beide würden je einen eigenen Blip setzen und je eine eigene Kopie desselben Charakters schreiben. Die Resource erkennt die Überschneidung und meldet das beim Start in der Konsole.

Sind die Tattoo-Namen übersetzt?

Sie werden gar nicht abgetippt: Jeder Eintrag trägt den Rockstar-Locale-Key, und das Spiel löst ihn in der Sprache des Spielers auf. Deshalb passen die Namen zu dem, was ein Spieler aus dem Story-Modus kennt, in jeder Sprache des Spiels, und deshalb muss nichts gepflegt werden, wenn sich ein Name ändert.

Was kostet es, wenn niemand im Shop ist?

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. Zwischen zwei Kunden läuft nichts.

Warenkorb
Spirit RP
Discord