Fahrzeuge¶
Besondere Fahrzeuge¶
| Model | Name |
|---|---|
| nkguardian | Abschlepper |
| onebeast | DOJ Limo |
FIB Fahrzeuge¶
| Model | Name |
|---|---|
| nkjugularum | FIB Jugular |
| nkpantoum | FIB Panto |
| nktailgatersum | FIB Tailgater |
MD Fahrzeuge (Medizin)¶
| Model | Name |
|---|---|
| nkambulance | MD Ambulance |
| nkballer7ems | MD Baller |
| nkstxems | MD Buffelo |
| nksvolitoems | MD Supervolito |
PD Fahrzeuge (Polizei)¶
| Model | Name |
|---|---|
| nkbuzzard | PD buzzard |
| nkcomet6 | PD Comet 6 |
| nkjugular | PD Jugular |
| nkpanto | PD Panto |
| nkscout | PD Scout |
| nkshinobi | PD Shinobi |
| nksvolito | PD Volito |
| nktailgaters | PD Tailgater |
| nkvigero2 | PD Vigero2 |
| insurgentpd | Metro Insurgent |
Luxusfahrzeuge¶
| Model | Name |
|---|---|
| LUMMA750 | Lumma 750 |
| bmm | Bentley Mulstenne |
| amggt63s | AMG GT63 |
| maybach | Maybach S650 |
| techart17 | Porsche Panamera Techart |
| rs6abt20 | Audi RS6 |
| rs318 | Audi RS3 |
| agerars | Agera RS |
| amggtbs | Balck Series |
| 69charger | Charger69 |
| corvetteZR1 | Corvette ZR1 |
| demon | Demon |
| eleanor | Eleanor |
| rmodm4gts | BMW M4 GTS |
| 911turbos | Porsche 911 Turbo |
| r6 | YamahaR6 |
| x6m | BMW X6 |
| urus | Lambo Urus |
| RSQ8M | Audi RS Q8 |
Kart Fahrzeuge¶
| Model | Name |
|---|---|
| PV_urus | Kart Urus |
| PV_sianr | Kart Sianr |
| PV_rover | Kart Rover |
| PV_dawn | Kart Rolls |
| PV_jeep | Kart Jeep |
| PV_gtr | Kart GTR |
| PV_lgss | Kart Gallardo |
| PV_bugvr | Kart Bugatti |
| --- |
Persistente Fahrzeug System¶
Ein robustes System zum Speichern und Laden von Fahrzeugen über Server-Restarts hinweg. Fahrzeuge können Charakteren, Unternehmen oder Fraktionen gehören.
Übersicht¶
Features¶
- ✅ Automatische Persistierung - Fahrzeuge werden auf dem Shutdown gespeichert und beim Start wiederhergestellt
- ✅ Multi-Owner Support - Charakter-, Unternehmens- und Faktionsfahrzeuge
- ✅ Vollständiger Zustand - Motor-, Karosserie- und Tankgesundheit bleiben erhalten
- ✅ Schadensmodellierung - Reifen, Türen, Fenster, Kratzer und Beulen
- ✅ Statebag Integration - Fahrzeug-IDs in FiveM Statebags gespeichert
- ✅ Benutzerdefinierte IDs - Eindeutige Fahrzeug-IDs für die Verwaltung
- ✅ Admin Commands - Debug- und Test-Commands für Administratoren
Datenbank-Schema¶
persistent_vehicles Tabelle¶
| Spalte | Typ | Beschreibung |
|---|---|---|
id |
INT | Primary Key |
veh_id |
VARCHAR(50) | Eindeutige persistente Fahrzeug-ID (Crypto, Format: veh_HEXSTRING) |
model |
VARCHAR(50) | Fahrzeugmodell (z.B. "blista", "rumpo") |
custom_id |
VARCHAR(50) | Optionale benutzerdefinierte Kennung |
owner_type |
ENUM | 'character', 'business', oder 'faction' |
owner_id |
INT | Charakter-/Unternehmens-/Fraktions-ID |
numplate |
VARCHAR(8) | Nummernschild (Auto-generiert, Format: AB 12345) |
location_x/y/z |
FLOAT | Aktueller Standort |
rotation_x/y/z |
FLOAT | Aktuelle Ausrichtung |
engine_health |
FLOAT | Motorgesundheit (0-1000) |
body_health |
FLOAT | Karosseriegesundheit (0-1000) |
tank_health |
FLOAT | Tankgesundheit (0-1000) |
fuel |
FLOAT | Kraftstoffmenge (0-100) |
tyres |
JSON | Reifenschaden pro Rad (0-7) |
doors |
JSON | Türschaden pro Tür (0-5) |
windows |
JSON | Fensterschaden pro Fenster (0-7) |
properties |
JSON | Zusätzliche Eigenschaften/Modifikationen |
Server-Funktionen¶
Fahrzeuge erstellen¶
Charakter-Fahrzeug erstellen¶
cv.createCharacterVehicle(
charId, -- number: Charakter-ID
model, -- string: Fahrzeugmodell
coords, -- vector3/table: {x, y, z}
heading, -- number: Ausrichtung
customId, -- string (optional): Benutzerdefinierte ID
callback -- function (optional): Callback bei Erfolg
)
Beispiel:
cv.createCharacterVehicle(1, "blista", vector3(425.5, -982.3, 29.4), 180.0, "my_car", function(veh)
if veh then
print("Charakter-Fahrzeug erstellt!")
end
end)
Unternehmens-Fahrzeug erstellen¶
cv.createBusinessVehicle(
businessId, -- number: Unternehmens-ID
model, -- string: Fahrzeugmodell
coords, -- vector3/table: Koordinaten
heading, -- number: Ausrichtung
customId, -- string (optional)
callback -- function (optional)
)
Beispiel:
Fraktions-Fahrzeug erstellen¶
cv.createFactionVehicle(
factionId, -- number: Fraktions-ID
model, -- string: Fahrzeugmodell
coords, -- vector3/table: Koordinaten
heading, -- number: Ausrichtung
customId, -- string (optional)
callback -- function (optional)
)
Beispiel:
Fahrzeuge abrufen¶
Einzelnes Fahrzeug abrufen¶
Alle Fahrzeuge eines Charakters¶
local vehicles = cv.getCharacterVehicles(charId)
for _, veh in ipairs(vehicles) do
print(veh.model .. " - " .. veh.numplate)
end
Alle Fahrzeuge eines Unternehmens¶
Alle Fahrzeuge einer Fraktion¶
Fahrzeuge verwalten¶
Fahrzeug-Zustand aktualisieren¶
cv.updatePersistentVehicleHealth(
veh_id, -- string: Fahrzeug-ID
engineHealth, -- number: Motor (0-1000)
bodyHealth, -- number: Karosserie (0-1000)
tankHealth, -- number: Tank (0-1000)
fuel, -- number: Kraftstoff (0-100)
properties -- table (optional): Zusätz. Eigenschaften
)
Beispiel:
Fahrzeug löschen¶
cv.deletePersistentVehicle(
veh_id, -- string: Fahrzeug-ID
deleteFromDB -- boolean (optional, default: true)
)
Beispiel:
Nummernschild-Verwaltung¶
Nummernschild-Format¶
Nummerschilder folgen strikten Regeln: - Erlaubte Zeichen: A-Z, 0-9, Leerzeichen - Länge: Max. 8 Zeichen - Format: Nur Leerzeichen zwischen Zeichen erlaubt (nicht am Anfang/Ende) - Mehrfach-Leerzeichen: Nicht erlaubt
Gültige Beispiele:
- ABC 1234
- AB 12345
- ABCD 123
Ungültige Beispiele:
- ABC1234 (Leerzeichen am Anfang)
- ABC1234 (Leerzeichen am Ende)
- AB 1234 (Doppel-Leerzeichen)
- abc1234 (Kleinbuchstaben)
Nummernschild-Verfügbarkeit prüfen¶
local available = cv.isPlateAvailable(plate)
if available then
print("Nummernschild verfügbar!")
else
print("Nummernschild bereits registriert")
end
Beispiel:
if cv.isPlateAvailable("ABC 1234") then
-- Nummernschild ist frei
else
-- Nummernschild vergeben
end
Nummernschild registrieren/ändern¶
local success = cv.registerVehiclePlate(
veh_id, -- string: Fahrzeug-ID
plate -- string: Neues Nummernschild
)
Rückgabewert:
- true - Erfolgreich registriert
- false - Ungültiges Format oder bereits vergeben
Beispiel:
if cv.registerVehiclePlate(veh_id, "ABC 1234") then
print("Nummernschild geändert!")
else
print("Nummernschild-Änderung fehlgeschlagen!")
end
In Fahrzeugerstellung:
cv.createCharacterVehicle(charId, "blista", coords, heading, nil, bucketId, function(veh)
if veh then
-- Fahrzeug wurde mit Auto-Nummernschild erstellt
local vehData = cv.getPersistentVehicle(veh_id)
print("Nummernschild: " .. vehData.numplate)
end
end)
Client-Funktionen¶
Prüfe ob Fahrzeug persistiert¶
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
if cv.isPersistentVehicle(vehicle) then
print("Das ist ein persistentes Fahrzeug!")
end
Hole Fahrzeug-ID¶
Hole Besitzer-Info¶
local ownerInfo = cv.getVehicleOwnerInfo(vehicle)
if ownerInfo then
print("Besitzer-Typ: " .. ownerInfo.owner_type)
print("Besitzer-ID: " .. ownerInfo.owner_id)
end
Gecachte Health-Werte¶
local engineHealth = cv.getVehicleEngineHealthCached(vehicle)
local bodyHealth = cv.getVehicleBodyHealthCached(vehicle)
Statebag-Eigenschaften¶
Jedes persistente Fahrzeug speichert automatisch folgende Werte im Statebag:
Entity(vehicle).state['persistentVehId'] -- Eindeutige Fahrzeug-ID
Entity(vehicle).state['ownerType'] -- 'character', 'business', 'faction'
Entity(vehicle).state['ownerId'] -- Besitzer-ID
Entity(vehicle).state['engineHealth'] -- Motorgesundheit (0-1000)
Entity(vehicle).state['bodyHealth'] -- Karosseriegesundheit (0-1000)
Diese Werte werden mit allen Clients synchronisiert.
Admin-Commands¶
/spawntest¶
Spawnt ein Test-Fahrzeug für den Charakter
Beispiele:/spawncompanycar¶
Spawnt ein Unternehmensfahrzeug (nur für Tests)
Beispiele:/pvdebug¶
Debug-Commands für das Fahrzeug-System
-count - Zeigt Anzahl der Fahrzeuge in der DB
- check - Zeigt Verteilung nach Besitzer-Typ
Praktische Beispiele¶
Beispiel 1: Fahrzeug-Flotte für Unternehmen¶
-- Erstelle 5 Lieferfahrzeuge für ein Unternehmen
for i = 1, 5 do
cv.createBusinessVehicle(1, "rumpo",
vector3(100 + i*10, 200, 30), 0.0,
"delivery_"..i
)
end
-- Rufe später alle Fahrzeuge ab
local vehicles = cv.getBusinessVehicles(1)
Beispiel 2: Persönliche Fahrzeuggarage¶
-- Charakter parkt sein Fahrzeug
cv.createCharacterVehicle(charId, "adder", coords, heading, "primary_vehicle")
-- Später im Garagen-Command
local vehicles = cv.getCharacterVehicles(charId)
for _, veh in ipairs(vehicles) do
if veh.custom_id == "primary_vehicle" then
-- Dieses Fahrzeug spawnen
end
end
Beispiel 3: Fraktions-Fahrzeuge¶
-- Polizei-Streifenwagen
cv.createFactionVehicle(1, "police", coords1, 0.0, "patrol_01")
cv.createFactionVehicle(1, "police", coords2, 90.0, "patrol_02")
-- Nach Neustart werden alle Fahrzeuge automatisch geladen
Beispiel 4: Fahrzeug-Health nach Unfall speichern¶
-- Nach Fahrzeug-Unfall
local vehicle = GetVehiclePedIsIn(PlayerPedId(), false)
if cv.isPersistentVehicle(vehicle) then
local veh_id = cv.getPersistentVehicleId(vehicle)
local engineHealth = GetVehicleEngineHealth(vehicle)
local bodyHealth = GetVehicleBodyHealth(vehicle)
-- Speichere den Schaden
cv.updatePersistentVehicleHealth(veh_id, engineHealth, bodyHealth, 1000, 65)
end
Automatisches Speichern/Laden¶
Server-Start¶
- Nach 1 Sekunde Verzögerung werden alle Fahrzeuge aus der DB geladen
- Standort und Ausrichtung werden wiederhergestellt
- Alle Health- und Schadenseigenschaften werden angewendet
- Statebag-Werte werden aktualisiert
Server-Shutdown¶
- Beim Herunterfahren (txAdmin oder Resource Stop) werden alle Fahrzeuge gespeichert
- Aktueller Standort, Ausrichtung und Health werden aufgezeichnet
- Schadenzustände (Reifen, Türen, Fenster) bleiben erhalten
- Alle Daten werden in die DB geschrieben
txAdmin-Integration¶
- Standard: Nutzt txAdmin
serverShuttingDownEvent - Fallback: Nutzt
onResourceStopwenn txAdmin nicht verfügbar - Config:
setr persistvehicles:useTxAdminEvent 1
Häufig gestellte Fragen¶
F: Wie lange dauert es, bis Fahrzeuge geladen werden? A: Fahrzeuge werden 1 Sekunde nach Server-Start geladen, um die DB-Verbindung zu initialisieren.
F: Können Fahrzeuge an neue Besitzer übertragen werden? A: Ja, durch direktes DB-Update:
MySQL.update.await(
'UPDATE persistent_vehicles SET owner_type = ?, owner_id = ? WHERE veh_id = ?',
{newType, newId, veh_id}
)
F: Bleiben Fahrzeug-Modifikationen erhalten?
A: Ja, alle Eigenschaften werden in der properties JSON-Spalte gespeichert.
F: Was passiert, wenn der Besitzer gelöscht wird? A: Derzeit bleiben die Fahrzeuge bestehen. Sie können Cleanup-Logik bei Charakter-Löschung hinzufügen.
F: Gibt es eine Obergrenze für Fahrzeuge? A: Nein, nur die MySQL-DB-Kapazität ist die Grenze.
Best Practices¶
- Verwende immer Callbacks - Fahrzeuge spawen asynchron
- Validiere Owner-IDs - Stelle sicher, dass Charakter/Unternehmens-IDs existieren
- Aktualisiere Health regelmäßig - Nutze
updatePersistentVehicleHealth()nach Änderungen - Verwende benutzerdefinierte IDs - Organisiere Fahrzeuge (z.B. "taxi_01", "police_k9")
- Prüfe auf Client - Nutze
cv.isPersistentVehicle()um Fahrzeugtyp zu checken - Nutze Statebag-Werte - Statt Entity-Abfragen mehrfach zu machen
Troubleshooting¶
Fahrzeuge werden nicht gespeichert¶
- Prüfe MySQL-Verbindung
- Verifiziere dass
persistent_vehiclesTabelle existiert - Schaue Server-Logs für SQL-Fehler
Fahrzeuge laden nicht nach Neustart¶
- Warte 1+ Sekunden nach Server-Start
- Prüfe DB auf Fahrzeug-Records
- Führe
/pvdebug countaus
Fahrzeug am falschen Ort¶
- Z-Koordinate müssen auf dem Boden sein
- Prüfe
rotation_z(Ausrichtung) in DB - Standort sollte keine Gebäude durchschneiden
Performance-Probleme¶
- Fahrzeuge werden mit Verzögerung nach Start geladen
- DB-Operationen sind synchron (
.await()) - Nur beim Shutdown wird gespeichert
- Minimaler Memory-Overhead
Integration mit cv_framework¶
- Nutzt existierendes
cv.spawnVehicle()System - Respektiert FiveM Bucket-Systeme
- Verwendet
MySQL.query/insert/update.await()für DB - Broadcast Statebag-Updates an alle Clients
- Integriert mit CVPlayer Character-System
FAQ - Benutzerdefinierte ID-Verwaltung¶
Fahrzeuge nach Custom-ID filtern¶
local allVehicles = cv.getCharacterVehicles(charId)
for _, veh in ipairs(allVehicles) do
if veh.custom_id == "primary_vehicle" then
print("Primär-Fahrzeug gefunden: " .. veh.model)
end
end