# Tattoo-Katalog

Der Katalog vereint Tattoos aus CXG Base und aus den Packs, die du installiert hast. Externe Packs sind optional: Du kannst keines, eines oder mehrere aktivieren. Fehlt ein Pack oder ist es gestoppt, werden seine Tattoos im Studio ausgeblendet; der CXG-Base-Katalog bleibt verfügbar.

Siehe auch [Einführung](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/01-introduccion.md), [Installation](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/02-instalacion.md), [Konfiguration](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/03-configuracion.md), [Integrationen](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/05-integraciones.md) und [Oberfläche](https://docs.cxgstudios.com/docs/de/01-cxg-tattoos/06-interfaz.md).

## Optionale Packs

Die Anfangskonfiguration enthält diese optionalen Quellen:

| ID | Ressource | Katalogdatei |
| --- | --- | --- |
| `xgc-classic` | `xgc_TattooClasic` | `tatoo_clasic_full_packconfigdump.json` |
| `xgc-gangs` | `xgc_TattooGangs` | `gangs_full_packconfigdump.json` |
| `xgc-japanese-mafia` | `xgc_TattooJapaneseMafia` | `japanese_mafia_full_packconfigdump.json` |
| `xgc-police` | `xgc_TattooPolice` | `police_full_packconfigdump.json` |
| `xgc-world-countries` | `xgc_TattooWorldCountries` | `world_country_full_packconfigdump.json` |
| `cxg-blackout` | `CXGtatoo_balckout` | `blackout_full_packconfigdump.json` |

Installiere nur Packs, die du besitzt, und starte sie vor `cxg-tattoos`. Behalte Ressourcenname und Pfad so bei, wie sie auf deinem Server vorhanden sind, einschließlich Groß- und Kleinschreibung. Um eine Quelle vorübergehend auszublenden, setze `enabled` auf `false`; zum erneuten Anzeigen setze es auf `true` und stelle sicher, dass die Ressource gestartet ist.

CXG Base verwendet `shared/tattoos.json` innerhalb der Ressource. Die Quelle `native-game` liest Designs aus den nativen Spiel-Tattoos und ist standardmäßig deaktiviert. Um sie zu verwenden, konfiguriere außerdem die Validierungsquellen in `native.serverMetas` mit den tatsächlichen Ressourcen und Dateien deines Servers. Der Beispieleintrag verweist auf `tatto` und `shop_tattoo.meta`; er setzt nicht voraus, dass diese Ressource installiert ist. `enabled` allein zu aktivieren garantiert nicht, dass diese Designs gekauft werden können.

## JSON-Quelle hinzufügen

Jedes Objekt in `Config.TattooCatalog.sources` konfiguriert eine Quelle. Dieses Beispiel folgt der Form der Pack-Ressourcen und lässt sich mit dem tatsächlichen Ressourcennamen und der zugehörigen Datei anpassen:

```lua
{
    id = 'mi-pack',
    label = 'Mi Pack',
    color = '#62b6cb',
    enabled = true,
    resource = 'mi_pack',
    path = 'tattoos.json',
    thumbnailPattern = 'miniatures/{Name}.webp',
    root = { mode = 'auto', field = 'Overlays' },
    defaults = {
        collection = 'mi_pack_overlays',
        zone = 'ZONE_TORSO',
        price = 5000,
        requiredLevel = 1,
        overlayTarget = 'male',
    },
}
```

`id` muss die Quelle stabil identifizieren; `label` und `color` dienen zu ihrer Erkennung in der Oberfläche. `resource` und `path` verweisen auf die JSON-Datei. Die Datei muss sich in einer verfügbaren Ressource befinden. Füge dasselbe Design nicht in zwei Quellen ein, außer wenn es zweimal erscheinen soll; `deduplicateAcrossSources` kann Duplikate zwischen Quellen entfernen.

Diese allgemeinen Einstellungen befinden sich in `Config.TattooCatalog`:

| Feld | Anfangswert | Verwendung |
| --- | --- | --- |
| `deduplicate` | `true` | Entfernt doppelte Designs innerhalb einer Quelle. |
| `deduplicateAcrossSources` | `false` | Lässt Designs aus verschiedenen Quellen getrennt bestehen. |
| `serverFallback` | `true` | Fordert eine Quelle vom Server an, wenn der Client sie nicht lesen kann. |
| `serverFallbackTimeoutMs` | `7000` | Maximale Wartezeit dieser Anfrage in Millisekunden. |

Der Lesefallback macht aus einem gestoppten Pack keine verfügbare Ressource.

## Format eines Tattoos

Die Datei kann ein JSON-Array oder ein Objekt sein, dessen Eigenschaft das Array enthält. Mit `root.mode = 'auto'` akzeptiert der Leser beide Formate; mit `root.mode = 'field'` gibt `root.field` den Speicherort der Liste an. `root.mode = 'array'` erzwingt ein Array an der Wurzel.

Dieses Array zeigt das JSON-Format. Die Sammlung und die Beispiel-Hashes sind fiktiv: Ersetze sie durch die tatsächlichen Namen des installierten Packs. Ein JSON-Eintrag installiert keine grafischen Overlays.

```json
[
  {
    "Collection": "mi_pack_overlays",
    "Name": "Rosa del desierto",
    "HashNameMale": "MP_MI_PACK_ROSE_M",
    "HashNameFemale": "MP_MI_PACK_ROSE_F",
    "Zone": "ZONE_TORSO",
    "Price": 5000,
    "Xp": 15,
    "RequiredLevel": 2
  }
]
```

`Collection` und mindestens ein Overlay-Hash sind erforderlich, um das Design zu identifizieren. Füge `HashNameMale` und `HashNameFemale` hinzu, wenn das Tattoo eine Variante für jeden Charakter hat. Verwende eine dieser Zonen: `ZONE_HEAD`, `ZONE_TORSO`, `ZONE_LEFT_ARM`, `ZONE_RIGHT_ARM`, `ZONE_LEFT_LEG` oder `ZONE_RIGHT_LEG`. `Name` ist der Name, den Käufer sehen. Wenn `Price` fehlt, wird der Standardpreis der Quelle verwendet; fehlt `RequiredLevel`, gilt `defaults.requiredLevel` mit dem Anfangswert 1. Die XP können vom Tattoo oder von der Levelkonfiguration stammen.

Bei Dateien mit anderen Feldnamen passe `fields` in `Config.TattooCatalog` an. Jeder Eintrag dieser Tabelle ist eine Liste von Aliasnamen, über die der entsprechende Wert gesucht wird. Eine Datei mit `OverlayHash`, `Cost` und `BodyZone` kann beispielsweise so zugeordnet werden:

```lua
fields = {
    collection = { 'Collection', 'CollectionName' },
    name = { 'Name', 'DisplayName' },
    overlay = { 'OverlayHash' },
    hashNameMale = { 'MaleOverlay' },
    hashNameFemale = { 'FemaleOverlay' },
    zone = { 'BodyZone' },
    price = { 'Cost' },
    xp = { 'Xp', 'Experience' },
    requiredLevel = { 'RequiredLevel' },
}
```

Über `rootFields` kannst du auch gemeinsame Werte wie Sammlungsnamen oder eine Zone zuweisen, die einmal im Stammobjekt definiert sind. `defaults` jeder Quelle ergänzt fehlende Werte. Wenn deine JSON-Datei nur ein allgemeines Feld wie `OverlayHash` enthält, gibt `defaults.overlayTarget` an, ob es als männliches (`male`) oder weibliches (`female`) Tattoo behandelt werden soll.

Stark abweichende Formate lassen sich mit den optionalen Funktionen `converters.decode(decoded, settings)` oder `converters.entry(entry, context)` in der Konfiguration umwandeln. Die erste passt das gesamte Dokument an, die zweite jedes einzelne Design. Gib eine Tabelle mit den Feldern zurück, die für die normale Zuordnung vorbereitet sind.

## Miniaturbilder

Um Bilder aus demselben Pack zu verwenden, behalte den Ordner `miniatures/` in dieser Ressource bei und definiere ein Muster wie:

```lua
thumbnailPattern = 'miniatures/{Name}.webp'
```

`{Name}`, `{HashNameMale}`, `{HashNameFemale}` und `{HashName}` werden durch Tattoo-Daten ersetzt. Die resultierende Datei muss innerhalb der Ressource vorhanden sein, zum Beispiel `miniatures/Rosa del desierto.webp`, und die Ressource muss gestartet sein. Die Oberfläche fordert Miniaturbilder bei Bedarf an; kopiere keine Bilder in das CXG-Paket.

Du kannst in einem Eintrag auch `Thumbnail` oder `ThumbnailUrl` angeben, um ein bestimmtes Bild festzulegen. URLs mit `http://`, `https://` und `data:` werden unverändert verwendet. Lokale Miniaturbilder eines Packs müssen zum `thumbnailPattern` passen; die Datei muss vorhanden und von der Ressource für die NUI bereitstellbar sein. Externe Ressourcen müssen ihre Datei im Pack behalten.

## Änderungen über Konfiguration und Administration

Bearbeite die Konfiguration, um Quellen hinzuzufügen, ihr Leseverhalten zu ändern, Packs zu aktivieren oder zu deaktivieren und ihre Standardwerte anzupassen. Verwende die Katalogverwaltung, um Namen, Preis, Level und Verfügbarkeit von Tattoos ohne Bearbeitung der JSON-Datei zu ändern. Administrative Änderungen werden gespeichert und bleiben bei Katalogsynchronisierungen erhalten. Mit der Aktion zum Wiederherstellen der Werte erhält das Tattoo seine Quellenwerte zurück.

Bereits gekaufte Tattoos bleiben an den Charakter eines Spielers gebunden, auch wenn das Pack, aus dem sie stammen, vorübergehend deaktiviert wird. Das Pack erscheint erst wieder im Studio, wenn es verfügbar ist.
