
Shops
Shop-System für das Standard-Inventar und ox_inventory: Läden mit Warenkorb, Waffenläden, rotierender Schwarzmarkt, Tagesangebote, NPC-Verkäufer und ein Shop-Editor im Spiel.
- ESX Legacy (
es_extended) - oxmysql
- Inventar: ESX-Standardinventar oder ox_inventory (wird beim Start erkannt)
- Optional: ox_target
Funktionen
- Drei Shop-Typen: Laden mit Warenkorb, Waffenladen und Schwarzmarkt. Bezahlt wird mit Karte oder Bar, auf dem Schwarzmarkt mit Schwarzgeld.
- Der Server prüft Preise, Summe, Gewicht und Entfernung. Lagerbestand nur bei gekauften Läden. Regeln pro Shop-Typ, Laden oder Item.
- Kaufbare Läden: Spieler kaufen einen Laden, legen Preise fest, holen Ware per Lieferfahrt beim Großhändler und verwalten die Kasse.
- Rotierender Schwarzmarkt mit wechselnden Standorten, Sortiment und Preisen, dazu Tagesangebote in normalen Läden.
- Shop-Editor im Spiel mit NPC-Modell, Szenario, Marker mit Live-Vorschau und eigenem Blip.
- Discord-Logs pro Kauf und Live-Statistik in Discord.
Installation
- Ordner
off_shopsin deinenresources-Ordner legen. - Alle Items aus
config/settings/config.items.luamüssen in deinem Inventar existieren – ESX: Tabelleitems, ox_inventory:ox_inventory/data/items.lua. Waffen (weapon_…) brauchen mit ESX keinen Eintrag. - In die
server.cfg– nach ESX, oxmysql und deinem Inventar:
ensure oxmysql
ensure es_extended
ensure ox_inventory
ensure off_shopsDie Tabellen werden automatisch angelegt und bei Updates ergänzt.
Konfiguration
config/settings/config.lua
| Option | Standard | Beschreibung |
|---|---|---|
serverInfo.name | 'OFF SCRIPTS' | Servername, steht in der Oberfläche statt „OFF SCRIPTS“ |
serverInfo.locale | 'de' | Sprache: de, en, pl, fr, es, it oder nl |
serverInfo.color | { 155, 89, 255 } | Farbe der UI (RGB) |
serverInfo.design | 3 | Design der Oberfläche: 1 = Klassisch, 2 = Kassenbon, 3 = Storefront |
blur | true | Hintergrund unscharf, solange der Shop offen ist. Der Editor bleibt scharf (Vorschau) |
useTarget | false | true = ox_target statt E |
pedSpeech | true | NPC begrüßt, verabschiedet und bedankt sich mit Stimme |
purchase.maxPerItem | 25 | Höchstmenge pro Artikel und Einkauf |
deals.enabled / count / discountPercent | false / 2 / 20 | Tagesangebote (nur normale Läden, keine Waffen): an/aus, Anzahl, Rabatt in Prozent |
marker.color / marker.alpha | { 155, 89, 255 } / 150 | Standardfarbe und Deckkraft der Marker |
editor.command / editor.groups | 'shopeditor' / { 'projektleitung' } | Befehl und ESX-Gruppen für den Editor |
stats.enabled / updateMinutes | true / 10 | Live-Statistik in Discord, Aktualisierung in Minuten |
blackmarket.rotation / activeLocations | 'day' / 1 | Wechsel des Schwarzmarkts ('day', 'week', 'month') und wie viele gleichzeitig da sind |
blackmarket.itemsPerCategory / priceVariancePercent | 2 / 15 | Artikel pro Kategorie im Zeitraum, Preisschwankung in Prozent |
shopTypes | normal, weapon, blackmarket | Pro Typ label, ped (Verkäufer), uiColor (eigene UI-Farbe), blip und rules |
Regeln (rules) gibt es pro Shop-Typ, Laden oder Item: jobs, blockedJobs, minGrade und hours = { from, to } (Ingame-Zeit, 22–5 = 22:00–04:59).
config/settings/config.locations.lua – Standorte
{ type = 'normal', label = 'LTD Davis', interactionType = 'ped', position = vec4(-47.02, -1758.23, 29.42, 45.05), categories = { 'food', 'drinks', 'tools' } },
{ type = 'blackmarket', interactionType = 'ped', position = vec4(14.2280, -1104.0475, 29.7970, 340.0), categories = { 'weapons', 'illegal' } },| Feld | Beschreibung |
|---|---|
type | 'normal', 'weapon' oder 'blackmarket' |
interactionType | 'ped' (NPC, vec4 mit Blickrichtung) oder 'marker' |
categories | Welche Kategorien der Laden verkauft |
price | Optional: Kaufpreis · ohne price ist der Laden nicht kaufbar |
label / rules / blip = false | Optional: eigener Name, eigene Regeln bzw. kein Kartensymbol |
Standorte mit type = 'blackmarket' sind mögliche Schwarzmarkt-Orte – davon sind activeLocations gleichzeitig aktiv.
Kategorien und Items
food = { label = 'Essen', items = { 'bread', 'kebab', 'wrap' } }, -- Kategorie
{ name = 'water', label = 'Wasser', price = 10 }, -- Item- Optional pro Item:
max(eigene Höchstmenge),image(eigenes Bild),rules(eigene Regeln). weapon_…wird als Waffe behandelt: einzeln kaufbar, mit 42 Schuss im ESX-Inventar, nicht doppelt.- Bilder: ESX lädt
web/dist/assets/items/<name>.png, ox_inventory nimmt seine eigenen. Fehlende Waffenbilder alsweb/dist/assets/weapons/<name>.pngablegen.
config/functions.lua
| Funktion | Wofür |
|---|---|
Notify(message, type) | Eigenes Notify · Server: Notify(source, message, type) |
HelpNotify(text) | Hinweistext am Verkäufer oder Marker |
Discord-Logs
Die Webhooks trägst du in config/settings/config.server.lua ein (nur serverseitig): purchases loggt jeden Einkauf, stats ist die Live-Statistik. Eine leere url ('') schaltet das Log aus.
Sprachen
Alle Texte stehen in config/locales/<sprache>.json. Für eine eigene Sprache eine Datei kopieren, übersetzen und locale setzen – Platzhalter wie %s und {total} drin lassen.
Im Spiel
Am Verkäufer oder Marker E drücken (oder ox_target), Artikel wählen und bezahlen. Im Laden gibt es einen Warenkorb, im Waffenladen und auf dem Schwarzmarkt wählst du einen Artikel.
Shop-Editor (/shopeditor)
- Links stehen alle Läden aus dem Editor. Läden aus der Config stehen nicht dort, die änderst du in
config/settings/config.locations.lua. - Neu legt einen Laden an deiner aktuellen Position an, Bearbeiten öffnet einen bestehenden.
- Einstellbar sind Typ, Name, Kategorien, NPC oder Marker, Position mit Blickrichtung und Blip.
- NPC: Modell aus einer Bilderliste aller GTA-Peds wählen (Suche und Kategorien), dazu Szenario und Blickrichtung, alles mit Live-Vorschau im Spiel. Ein Addon-Ped wählst du über den genauen Modellnamen in der Suche. Standard = Verkäufer aus
shopTypes. - Marker: Typ, Größe, Bodenabstand, Rotation, Farbe, Deckkraft und Bewegung mit Live-Vorschau im Spiel.
- Blip: an oder aus, optional mit eigenem Symbol und eigener Farbe. Sonst gilt der Blip aus
shopTypes. - Solange der Editor offen ist, läufst du mit WASD und schaust dich mit gedrückter rechter Maustaste um. Dann Position übernehmen drücken.
- Nach Speichern gilt die Änderung sofort für alle Spieler. Ein Schwarzmarkt aus dem Editor steht fest und verkauft alle Artikel seiner Kategorien.
Kaufbare Läden
Ob ein Laden kaufbar ist, stellst du bei Config-Läden mit price in config.locations.lua ein, bei Editor-Läden im Shop-Editor (Gruppe Besitz: Kaufbar, Kaufpreis). Der Schwarzmarkt ist nie kaufbar. Nicht gekaufte Läden verkaufen wie gewohnt ohne Lagerbestand.
Option (ownership) | Standard | Beschreibung |
|---|---|---|
enabled | true | Kaufbare Läden an/aus. Aus = alles wie ohne die Funktion |
maxPerPlayer | 1 | Wie viele Läden ein Spieler besitzen darf |
startStock / maxStock | 20 / 200 | Startbestand pro Artikel nach dem Kauf / Höchstbestand pro Artikel |
priceRange.min / max | 0.8 / 1.5 | Erlaubter Verkaufspreis = Grundpreis × min bis max |
wholesaleFactor | 0.6 | Großhandelspreis = Grundpreis × Faktor |
sellBackPercent | 60 | Rückkauf durch den Server in % vom Kaufpreis |
van / orderMaxUnits / orderMinutes | 'speedo' / 300 / 20 | Lieferwagen, max. Stück pro Fahrt, Zeitlimit in Minuten |
vanSpawn | vec4(...) | Spawn-Punkt des Lieferwagens, der Spieler wird dorthin teleportiert |
refundPercent | 0 | Erstattung in % bei gescheiterter oder abgebrochener Lieferfahrt |
wholesalers | 3 × vec3 | Großhändler, angefahren wird der nächste zum Laden |
Im Spiel: Bei einem kaufbaren Laden öffnet E zuerst eine Auswahl Einkaufen oder Verwaltung, bei einem NPC mit Kamera auf den Verkäufer. Gehört der Laden jemand anderem, öffnet sich direkt der Shop. Ohne Besitzer führt Verwaltung zum Kaufangebot, als Besitzer in die Verwaltung mit Übersicht (Kasse, Umsatz heute/7 Tage/gesamt, Diagramm, fast ausverkaufte Artikel), Lager, Preise, Bestellung und Kasse (Ein-/Auszahlen bar oder aufs Konto, Verlauf, Laden verkaufen). Kunden zahlen in die Kasse und können nur kaufen, was auf Lager ist.
Lieferfahrt: Ware wählen, die Kosten gehen aus der Kasse. Du wirst zum Spawn-Punkt vanSpawn teleportiert und in den Lieferwagen gesetzt – zum Großhändler fahren, in der Markierung E (einladen), zurückfahren und den Wagen in der Markierung abstellen, dann zum Verkäufer gehen und E drücken. Erst dann kommt die Ware ins Lager. Wird der Wagen zerstört, läuft die Zeit ab oder verlässt du den Server, ist die Ware weg (Erstattung laut refundPercent). Nach einem Server-Neustart wird eine offene Fahrt voll erstattet.
Discord-Log: Webhook ownership in config/settings/config.server.lua (Kauf, Verkauf, Lieferfahrten, Ein-/Auszahlungen). Freigeben im Editor macht einen Laden wieder frei (Lager und Kasse verfallen).
Häufige Fehler
| Problem | Lösung |
|---|---|
[ERROR] in der Server-Konsole | Das Script prüft beim Start die Einrichtung. Meldung lesen, beheben, Script neu starten. |
| „Dieser Artikel ist ungültig“ | Item fehlt im Inventar (ESX: Tabelle items, ox_inventory: items.lua). |
| ox_inventory wird nicht erkannt | ensure ox_inventory muss vor off_shops stehen. |
| Schwarzmarkt ist geschlossen | Standardmäßig nur 22–5 Uhr Ingame-Zeit (rules.hours). |
| Schwarzmarkt ist nicht da | Nur activeLocations Standorte sind aktiv – die anderen beim nächsten Wechsel. |
| Schwarzmarkt: „Zu wenig Geld“ | Der Schwarzmarkt nimmt nur Schwarzgeld (black_money). |
/shopeditor öffnet sich nicht | Deine ESX-Gruppe muss in editor.groups stehen. |
| „Das NPC-Modell … gibt es nicht“ | Modellnamen prüfen, z. B. mp_m_shopkeep_01. Addon-Peds müssen gestreamt sein. |
Noch nicht gekauft?
Shops im Shop ansehen