local QBCore = exports['qb-core']:GetCoreObject() local playerDrivenVehicles = {} -- Nur Fahrzeuge die der Spieler gefahren hat -- Funktion um zu prüfen ob Fahrzeugklasse erlaubt ist local function IsVehicleClassAllowed(vehicle) local vehicleClass = GetVehicleClass(vehicle) for _, allowedClass in pairs(Config.AllowedVehicleClasses) do if vehicleClass == allowedClass then return true end end return false end -- Funktion um Fahrzeugmods zu erhalten local function GetVehicleMods(vehicle) local mods = {} -- Basis Mods for i = 0, 49 do mods[tostring(i)] = GetVehicleMod(vehicle, i) end -- Extras mods.extras = {} for i = 1, 12 do if DoesExtraExist(vehicle, i) then mods.extras[tostring(i)] = IsVehicleExtraTurnedOn(vehicle, i) end end -- Farben local primaryColor, secondaryColor = GetVehicleColours(vehicle) local pearlescentColor, wheelColor = GetVehicleExtraColours(vehicle) mods.colors = { primary = primaryColor, secondary = secondaryColor, pearlescent = pearlescentColor, wheels = wheelColor } -- Neon mods.neon = { left = IsVehicleNeonLightEnabled(vehicle, 0), right = IsVehicleNeonLightEnabled(vehicle, 1), front = IsVehicleNeonLightEnabled(vehicle, 2), back = IsVehicleNeonLightEnabled(vehicle, 3) } local r, g, b = GetVehicleNeonLightsColour(vehicle) mods.neonColor = {r = r, g = g, b = b} return mods end -- Funktion um Fahrzeugmods zu setzen local function SetVehicleMods(vehicle, mods) if not mods then return end -- Basis Mods for i = 0, 49 do if mods[tostring(i)] then SetVehicleMod(vehicle, i, mods[tostring(i)], false) end end -- Extras if mods.extras then for i = 1, 12 do if mods.extras[tostring(i)] ~= nil then SetVehicleExtra(vehicle, i, not mods.extras[tostring(i)]) end end end -- Farben if mods.colors then SetVehicleColours(vehicle, mods.colors.primary or 0, mods.colors.secondary or 0) SetVehicleExtraColours(vehicle, mods.colors.pearlescent or 0, mods.colors.wheels or 0) end -- Neon if mods.neon then SetVehicleNeonLightEnabled(vehicle, 0, mods.neon.left or false) SetVehicleNeonLightEnabled(vehicle, 1, mods.neon.right or false) SetVehicleNeonLightEnabled(vehicle, 2, mods.neon.front or false) SetVehicleNeonLightEnabled(vehicle, 3, mods.neon.back or false) end if mods.neonColor then SetVehicleNeonLightsColour(vehicle, mods.neonColor.r, mods.neonColor.g, mods.neonColor.b) end end -- Event Handler für Fahrzeug betreten (nur Fahrersitz) CreateThread(function() local lastVehicle = 0 while true do Wait(1000) local playerPed = PlayerPedId() local currentVehicle = GetVehiclePedIsIn(playerPed, false) -- Spieler ist als Fahrer in ein Fahrzeug eingestiegen if currentVehicle ~= 0 and currentVehicle ~= lastVehicle then local seat = GetPedVehicleSeat(playerPed) -- Nur wenn Spieler auf Fahrersitz ist (Seat -1) if seat == -1 and IsVehicleClassAllowed(currentVehicle) then local plate = QBCore.Functions.GetPlate(currentVehicle) playerDrivenVehicles[plate] = currentVehicle -- Verhindere sofort Despawn SetEntityAsMissionEntity(currentVehicle, true, true) SetVehicleHasBeenOwnedByPlayer(currentVehicle, true) if Config.Debug then print(string.format("Player started driving vehicle: %s", plate)) end end end lastVehicle = currentVehicle end end) -- Hauptloop für Fahrzeugtracking (nur für vom Spieler gefahrene Fahrzeuge) CreateThread(function() while true do Wait(Config.SaveInterval) -- Tracke nur Fahrzeuge die der Spieler gefahren hat for plate, vehicle in pairs(playerDrivenVehicles) do if DoesEntityExist(vehicle) then local vehicleCoords = GetEntityCoords(vehicle) -- Verhindere Despawn SetEntityAsMissionEntity(vehicle, true, true) SetVehicleHasBeenOwnedByPlayer(vehicle, true) -- Speichere Fahrzeugdaten local vehicleData = { plate = plate, model = GetEntityModel(vehicle), position = {x = vehicleCoords.x, y = vehicleCoords.y, z = vehicleCoords.z}, rotation = {x = 0.0, y = 0.0, z = GetEntityHeading(vehicle)}, engineHealth = GetVehicleEngineHealth(vehicle), bodyHealth = GetVehicleBodyHealth(vehicle), fuel = 100, mods = GetVehicleMods(vehicle) } -- Versuche Fuel zu bekommen if GetResourceState('LegacyFuel') == 'started' then vehicleData.fuel = exports['LegacyFuel']:GetFuel(vehicle) or 100 elseif GetResourceState('ps-fuel') == 'started' then vehicleData.fuel = exports['ps-fuel']:GetFuel(vehicle) or 100 end TriggerServerEvent('vehicle-persistence:server:saveVehiclePosition', vehicleData) if Config.Debug then print(string.format("Saving player driven vehicle: %s", plate)) end else -- Fahrzeug existiert nicht mehr, entferne aus Liste playerDrivenVehicles[plate] = nil if Config.Debug then print(string.format("Player driven vehicle no longer exists: %s", plate)) end end end end end) -- Spawne gespeicherte Fahrzeuge RegisterNetEvent('vehicle-persistence:client:spawnSavedVehicles', function(vehicles) if Config.Debug then print(string.format("Attempting to spawn %d saved vehicles", #vehicles)) end for _, vehicleData in pairs(vehicles) do local position = json.decode(vehicleData.position) local rotation = json.decode(vehicleData.rotation) -- Prüfe ob Fahrzeug bereits existiert local existingVehicle = GetVehicleByPlate(vehicleData.plate) if not existingVehicle then CreateThread(function() local modelHash = vehicleData.model if type(modelHash) == "string" then modelHash = GetHashKey(modelHash) end RequestModel(modelHash) local timeout = 0 while not HasModelLoaded(modelHash) and timeout < 50 do Wait(100) timeout = timeout + 1 end if HasModelLoaded(modelHash) then local vehicle = CreateVehicle(modelHash, position.x, position.y, position.z, rotation.z, true, false) if DoesEntityExist(vehicle) then Wait(500) -- Setze Fahrzeugdaten SetVehicleNumberPlateText(vehicle, vehicleData.plate) SetVehicleEngineHealth(vehicle, vehicleData.engine_health or 1000.0) SetVehicleBodyHealth(vehicle, vehicleData.body_health or 1000.0) -- Setze Fuel if GetResourceState('LegacyFuel') == 'started' then exports['LegacyFuel']:SetFuel(vehicle, vehicleData.fuel or 100) elseif GetResourceState('ps-fuel') == 'started' then exports['ps-fuel']:SetFuel(vehicle, vehicleData.fuel or 100) end -- Setze Mods if vehicleData.mods then local mods = json.decode(vehicleData.mods) SetVehicleMods(vehicle, mods) end -- Verhindere Despawn SetEntityAsMissionEntity(vehicle, true, true) SetVehicleHasBeenOwnedByPlayer(vehicle, true) playerDrivenVehicles[vehicleData.plate] = vehicle if Config.Debug then print(string.format("Successfully spawned saved vehicle: %s", vehicleData.plate)) end end SetModelAsNoLongerNeeded(modelHash) end end) else -- Fahrzeug existiert bereits, füge zu Liste hinzu playerDrivenVehicles[vehicleData.plate] = existingVehicle SetEntityAsMissionEntity(existingVehicle, true, true) SetVehicleHasBeenOwnedByPlayer(existingVehicle, true) end end end) -- Hilfsfunktion um Fahrzeug anhand Kennzeichen zu finden function GetVehicleByPlate(plate) local vehicles = GetGamePool('CVehicle') for _, vehicle in pairs(vehicles) do if QBCore.Functions.GetPlate(vehicle) == plate then return vehicle end end return nil end -- Lade Fahrzeuge beim Spawn RegisterNetEvent('QBCore:Client:OnPlayerLoaded', function() Wait(10000) TriggerServerEvent('vehicle-persistence:server:loadVehicles') end) -- jg-advanced-garage Events RegisterNetEvent('jg-advancedgarages:client:vehicle-stored', function(data) if data and data.plate and playerDrivenVehicles[data.plate] then playerDrivenVehicles[data.plate] = nil if Config.Debug then print(string.format("Vehicle stored in garage, removed from tracking: %s", data.plate)) end end end) RegisterNetEvent('jg-advancedgarages:client:vehicle-spawned', function(data) if data and data.plate and playerDrivenVehicles[data.plate] then playerDrivenVehicles[data.plate] = nil if Config.Debug then print(string.format("Vehicle spawned from garage, removed from tracking: %s", data.plate)) end end end) -- Cleanup beim Disconnect AddEventHandler('onResourceStop', function(resourceName) if resourceName == GetCurrentResourceName() then playerDrivenVehicles = {} end end)