503 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			503 lines
		
	
	
	
		
			17 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
local QBCore = exports['qb-core']:GetCoreObject()
 | 
						|
local spawnedNPCs = {}
 | 
						|
local activeRentalVehicles = {}
 | 
						|
 | 
						|
-- NPCs spawnen
 | 
						|
CreateThread(function()
 | 
						|
    -- Warte kurz, bis die Welt geladen ist
 | 
						|
    Wait(2000)
 | 
						|
    
 | 
						|
    for i = 1, #Config.RentalLocations do
 | 
						|
        local location = Config.RentalLocations[i]
 | 
						|
        local modelHash = GetHashKey(location.npc.model)
 | 
						|
        
 | 
						|
        -- Modell laden
 | 
						|
        RequestModel(modelHash)
 | 
						|
        local timeout = 0
 | 
						|
        while not HasModelLoaded(modelHash) and timeout < 30 do
 | 
						|
            Wait(100)
 | 
						|
            timeout = timeout + 1
 | 
						|
        end
 | 
						|
        
 | 
						|
        if HasModelLoaded(modelHash) then
 | 
						|
            -- NPC erstellen
 | 
						|
            local coords = location.npc.coords
 | 
						|
            local npc = CreatePed(4, modelHash, coords.x, coords.y, coords.z - 1.0, coords.w, false, false)
 | 
						|
            
 | 
						|
            -- NPC-Eigenschaften setzen
 | 
						|
            FreezeEntityPosition(npc, true)
 | 
						|
            SetEntityInvincible(npc, true)
 | 
						|
            SetBlockingOfNonTemporaryEvents(npc, true)
 | 
						|
            SetPedDefaultComponentVariation(npc)
 | 
						|
            
 | 
						|
            -- NPC speichern
 | 
						|
            spawnedNPCs[location.id] = npc
 | 
						|
            
 | 
						|
            -- Debug-Info
 | 
						|
            print("NPC spawned at location: " .. location.name)
 | 
						|
            
 | 
						|
            -- QB-Target für NPC
 | 
						|
            exports['qb-target']:AddTargetEntity(npc, {
 | 
						|
                options = {
 | 
						|
                    {
 | 
						|
                        type = "client",
 | 
						|
                        event = "vehiclerental:client:openMenu",
 | 
						|
                        icon = "fas fa-car",
 | 
						|
                        label = "Fahrzeug mieten",
 | 
						|
                        locationId = location.id
 | 
						|
                    },
 | 
						|
                    {
 | 
						|
                        type = "client",
 | 
						|
                        event = "vehiclerental:client:returnVehicle",
 | 
						|
                        icon = "fas fa-car-side",
 | 
						|
                        label = "Fahrzeug zurückgeben",
 | 
						|
                        locationId = location.id
 | 
						|
                    }
 | 
						|
                },
 | 
						|
                distance = 2.0
 | 
						|
            })
 | 
						|
        else
 | 
						|
            print("Failed to load NPC model for location: " .. location.name)
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Mietmenü öffnen
 | 
						|
RegisterNetEvent('vehiclerental:client:openMenu', function(data)
 | 
						|
    local locationId = data.locationId
 | 
						|
    local location = nil
 | 
						|
    
 | 
						|
    for i = 1, #Config.RentalLocations do
 | 
						|
        if Config.RentalLocations[i].id == locationId then
 | 
						|
            location = Config.RentalLocations[i]
 | 
						|
            break
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    if not location then return end
 | 
						|
 | 
						|
    local options = {}
 | 
						|
    for i = 1, #location.vehicles do
 | 
						|
        local vehicle = location.vehicles[i]
 | 
						|
        table.insert(options, {
 | 
						|
            title = vehicle.label,
 | 
						|
            description = '$' .. vehicle.price .. ' pro Stunde',
 | 
						|
            icon = 'car',
 | 
						|
            onSelect = function()
 | 
						|
                openRentalDialog(vehicle, location)
 | 
						|
            end
 | 
						|
        })
 | 
						|
    end
 | 
						|
 | 
						|
    lib.registerContext({
 | 
						|
        id = 'vehicle_rental_menu',
 | 
						|
        title = location.name,
 | 
						|
        options = options
 | 
						|
    })
 | 
						|
 | 
						|
    lib.showContext('vehicle_rental_menu')
 | 
						|
end)
 | 
						|
 | 
						|
-- Mietdialog
 | 
						|
function openRentalDialog(vehicle, location)
 | 
						|
    local input = lib.inputDialog('Fahrzeug mieten', {
 | 
						|
        {
 | 
						|
            type = 'number',
 | 
						|
            label = 'Mietdauer (Stunden)',
 | 
						|
            description = 'Maximale Mietdauer: ' .. Config.MaxRentalTime .. ' Stunden',
 | 
						|
            required = true,
 | 
						|
            min = 1,
 | 
						|
            max = Config.MaxRentalTime
 | 
						|
        }
 | 
						|
    })
 | 
						|
 | 
						|
    if not input or not input[1] then return end
 | 
						|
 | 
						|
    local hours = tonumber(input[1])
 | 
						|
    if not hours or hours < 1 or hours > Config.MaxRentalTime then
 | 
						|
        QBCore.Functions.Notify('Ungültige Mietdauer!', 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
 | 
						|
    local totalCost = vehicle.price * hours
 | 
						|
    local plate = GeneratePlate()
 | 
						|
 | 
						|
    QBCore.Functions.TriggerCallback('vehiclerental:server:rentVehicle', function(success)
 | 
						|
        if success then
 | 
						|
            spawnRentalVehicle(vehicle.model, location.spawnPoint, plate)
 | 
						|
        end
 | 
						|
    end, {
 | 
						|
        vehicleModel = vehicle.model,
 | 
						|
        pricePerHour = vehicle.price,
 | 
						|
        hours = hours,
 | 
						|
        locationId = location.id,
 | 
						|
        plate = plate
 | 
						|
    })
 | 
						|
end
 | 
						|
 | 
						|
-- Fahrzeug spawnen
 | 
						|
function spawnRentalVehicle(model, spawnPoint, plate)
 | 
						|
    RequestModel(model)
 | 
						|
    while not HasModelLoaded(model) do
 | 
						|
        Wait(1)
 | 
						|
    end
 | 
						|
 | 
						|
    local vehicle = CreateVehicle(model, spawnPoint.x, spawnPoint.y, spawnPoint.z, spawnPoint.w, true, false)
 | 
						|
    SetVehicleNumberPlateText(vehicle, plate)
 | 
						|
    SetEntityAsMissionEntity(vehicle, true, true)
 | 
						|
    TaskWarpPedIntoVehicle(PlayerPedId(), vehicle, -1)
 | 
						|
    
 | 
						|
    TriggerEvent("vehiclekeys:client:SetOwner", plate)
 | 
						|
    SetModelAsNoLongerNeeded(model)
 | 
						|
    
 | 
						|
    -- Speichere das Fahrzeug lokal
 | 
						|
    activeRentalVehicles[plate] = vehicle
 | 
						|
    
 | 
						|
    -- Speichere die initiale Position
 | 
						|
    local pos = GetEntityCoords(vehicle)
 | 
						|
    local rot = GetEntityRotation(vehicle)
 | 
						|
    TriggerServerEvent('vehiclerental:server:updatePosition', plate, pos, rot)
 | 
						|
    
 | 
						|
    print("[VehicleRental] Neues Mietfahrzeug erstellt: " .. plate)
 | 
						|
end
 | 
						|
 | 
						|
-- Fahrzeug zurückgeben
 | 
						|
RegisterNetEvent('vehiclerental:client:returnVehicle', function(data)
 | 
						|
    -- Hole alle aktiven Mietverhältnisse des Spielers
 | 
						|
    QBCore.Functions.TriggerCallback('vehiclerental:server:getPlayerRentals', function(rentals)
 | 
						|
        if not rentals or #rentals == 0 then
 | 
						|
            QBCore.Functions.Notify('Du hast keine aktiven Mietverhältnisse!', 'error')
 | 
						|
            return
 | 
						|
        end
 | 
						|
 | 
						|
        -- Erstelle Menü mit allen gemieteten Fahrzeugen
 | 
						|
        local options = {}
 | 
						|
        for i = 1, #rentals do
 | 
						|
            local rental = rentals[i]
 | 
						|
            
 | 
						|
            table.insert(options, {
 | 
						|
                title = rental.vehicle_model .. " - " .. rental.vehicle_plate,
 | 
						|
                description = "Zurückgeben " .. rental.timeText,
 | 
						|
                icon = 'car',
 | 
						|
                onSelect = function()
 | 
						|
                    returnSpecificVehicle(rental.vehicle_plate, data.locationId)
 | 
						|
                end
 | 
						|
            })
 | 
						|
        end
 | 
						|
 | 
						|
        lib.registerContext({
 | 
						|
            id = 'return_vehicle_menu',
 | 
						|
            title = 'Fahrzeug zurückgeben',
 | 
						|
            options = options
 | 
						|
        })
 | 
						|
 | 
						|
        lib.showContext('return_vehicle_menu')
 | 
						|
    end)
 | 
						|
end)
 | 
						|
 | 
						|
-- Fahrzeug löschen (wie DV-Befehl)
 | 
						|
function DeleteRentalVehicle(vehicle)
 | 
						|
    if DoesEntityExist(vehicle) then
 | 
						|
        -- Standard FiveM-Methode zum Löschen von Fahrzeugen (wie DV-Befehl)
 | 
						|
        SetEntityAsMissionEntity(vehicle, true, true)
 | 
						|
        DeleteEntity(vehicle)
 | 
						|
        
 | 
						|
        if DoesEntityExist(vehicle) then
 | 
						|
            -- Zweiter Versuch mit DeleteVehicle
 | 
						|
            DeleteVehicle(vehicle)
 | 
						|
        end
 | 
						|
        
 | 
						|
        -- Prüfe, ob das Fahrzeug wirklich gelöscht wurde
 | 
						|
        if not DoesEntityExist(vehicle) then
 | 
						|
            return true
 | 
						|
        else
 | 
						|
            -- Letzter Versuch mit NetworkFadeOutEntity
 | 
						|
            NetworkFadeOutEntity(vehicle, true, true)
 | 
						|
            Wait(500)
 | 
						|
            DeleteEntity(vehicle)
 | 
						|
            return not DoesEntityExist(vehicle)
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return true -- Fahrzeug existiert nicht, also gilt es als gelöscht
 | 
						|
end
 | 
						|
 | 
						|
-- Spezifisches Fahrzeug zurückgeben
 | 
						|
function returnSpecificVehicle(plate, locationId)
 | 
						|
    -- Finde die Location-Daten
 | 
						|
    local location = nil
 | 
						|
    for i = 1, #Config.RentalLocations do
 | 
						|
        if Config.RentalLocations[i].id == locationId then
 | 
						|
            location = Config.RentalLocations[i]
 | 
						|
            break
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    if not location then
 | 
						|
        QBCore.Functions.Notify('Fehler beim Finden des Rückgabeorts!', 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Definiere den Rückgabeort
 | 
						|
    local returnPoint = vector3(location.returnPoint.x, location.returnPoint.y, location.returnPoint.z)
 | 
						|
    
 | 
						|
    -- Finde das Fahrzeug in der Nähe
 | 
						|
    local vehicle = nil
 | 
						|
    local closestDistance = 50.0 -- Maximale Suchentfernung
 | 
						|
    
 | 
						|
    -- Suche nach dem Fahrzeug mit dem Kennzeichen
 | 
						|
    for veh in EnumerateVehicles() do
 | 
						|
        local vehPlate = GetVehicleNumberPlateText(veh)
 | 
						|
        if string.gsub(vehPlate, "%s+", "") == string.gsub(plate, "%s+", "") then
 | 
						|
            local vehPos = GetEntityCoords(veh)
 | 
						|
            local distance = #(returnPoint - vehPos)
 | 
						|
            
 | 
						|
            if distance < closestDistance then
 | 
						|
                vehicle = veh
 | 
						|
                closestDistance = distance
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
 | 
						|
    if not vehicle then
 | 
						|
        QBCore.Functions.Notify('Fahrzeug nicht in der Nähe des Rückgabeorts gefunden!', 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
 | 
						|
    -- Prüfe ob das Fahrzeug nahe genug am Rückgabeort ist
 | 
						|
    local vehPos = GetEntityCoords(vehicle)
 | 
						|
    local distance = #(returnPoint - vehPos)
 | 
						|
    
 | 
						|
    if distance > Config.MaxReturnDistance then
 | 
						|
        QBCore.Functions.Notify('Das Fahrzeug muss näher am Rückgabeort sein! (Max. ' .. Config.MaxReturnDistance .. 'm)', 'error')
 | 
						|
        return
 | 
						|
    end
 | 
						|
 | 
						|
    -- Fahrzeug zurückgeben
 | 
						|
    QBCore.Functions.TriggerCallback('vehiclerental:server:returnVehicle', function(success)
 | 
						|
        if success then
 | 
						|
            -- Fahrzeug mit DV-ähnlicher Methode löschen
 | 
						|
            if DeleteRentalVehicle(vehicle) then
 | 
						|
                QBCore.Functions.Notify('Fahrzeug erfolgreich zurückgegeben!', 'success')
 | 
						|
            else
 | 
						|
                QBCore.Functions.Notify('Fahrzeug zurückgegeben, aber konnte nicht vollständig gelöscht werden.', 'warning')
 | 
						|
            end
 | 
						|
            
 | 
						|
            -- Aus lokaler Tracking-Liste entfernen
 | 
						|
            activeRentalVehicles[plate] = nil
 | 
						|
        end
 | 
						|
    end, plate)
 | 
						|
end
 | 
						|
 | 
						|
-- Lade alle aktiven Mietfahrzeuge
 | 
						|
RegisterNetEvent('vehiclerental:client:loadRentals')
 | 
						|
AddEventHandler('vehiclerental:client:loadRentals', function(rentals)
 | 
						|
    -- Lösche alle vorhandenen Mietfahrzeuge
 | 
						|
    for plate, vehicle in pairs(activeRentalVehicles) do
 | 
						|
        if DoesEntityExist(vehicle) then
 | 
						|
            DeleteRentalVehicle(vehicle)
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    activeRentalVehicles = {}
 | 
						|
    
 | 
						|
    -- Spawne alle aktiven Mietfahrzeuge
 | 
						|
    for _, rental in ipairs(rentals) do
 | 
						|
        -- Prüfe, ob das Fahrzeug dem aktuellen Spieler gehört
 | 
						|
        local playerCitizenId = QBCore.Functions.GetPlayerData().citizenid
 | 
						|
        
 | 
						|
        if rental.citizenid == playerCitizenId then
 | 
						|
            -- Spawne das Fahrzeug nur, wenn es eine Position hat
 | 
						|
            if rental.posX ~= 0 or rental.posY ~= 0 or rental.posZ ~= 0 then
 | 
						|
                Citizen.CreateThread(function()
 | 
						|
                    local model = rental.vehicle_model
 | 
						|
                    local plate = rental.vehicle_plate
 | 
						|
                    
 | 
						|
                    -- Lade das Modell
 | 
						|
                    RequestModel(model)
 | 
						|
                    while not HasModelLoaded(model) do
 | 
						|
                        Citizen.Wait(10)
 | 
						|
                    end
 | 
						|
                    
 | 
						|
                    -- Spawne das Fahrzeug
 | 
						|
                    local vehicle = CreateVehicle(model, 
 | 
						|
                        rental.posX, rental.posY, rental.posZ, 
 | 
						|
                        rental.rotZ or 0.0, true, false)
 | 
						|
                    
 | 
						|
                    -- Setze Eigenschaften
 | 
						|
                    SetVehicleNumberPlateText(vehicle, plate)
 | 
						|
                    SetEntityAsMissionEntity(vehicle, true, true)
 | 
						|
                    SetVehicleDoorsLocked(vehicle, 2) -- Abgeschlossen
 | 
						|
                    
 | 
						|
                    -- Setze Rotation
 | 
						|
                    SetEntityRotation(vehicle, 
 | 
						|
                        rental.rotX or 0.0, 
 | 
						|
                        rental.rotY or 0.0, 
 | 
						|
                        rental.rotZ or 0.0, 
 | 
						|
                        2, true)
 | 
						|
                    
 | 
						|
                    -- Gib dem Spieler die Schlüssel
 | 
						|
                    TriggerEvent("vehiclekeys:client:SetOwner", plate)
 | 
						|
                    
 | 
						|
                    -- Speichere das Fahrzeug lokal
 | 
						|
                    activeRentalVehicles[plate] = vehicle
 | 
						|
                    
 | 
						|
                    print("[VehicleRental] Mietfahrzeug geladen: " .. plate)
 | 
						|
                end)
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Fahrzeug zurückgegeben
 | 
						|
RegisterNetEvent('vehiclerental:client:vehicleReturned')
 | 
						|
AddEventHandler('vehiclerental:client:vehicleReturned', function(plate)
 | 
						|
    -- Lösche das Fahrzeug, wenn es existiert
 | 
						|
    if activeRentalVehicles[plate] then
 | 
						|
        local vehicle = activeRentalVehicles[plate]
 | 
						|
        DeleteRentalVehicle(vehicle)
 | 
						|
        activeRentalVehicles[plate] = nil
 | 
						|
        print("[VehicleRental] Mietfahrzeug gelöscht: " .. plate)
 | 
						|
    end
 | 
						|
    
 | 
						|
    -- Suche nach dem Fahrzeug in der Welt anhand des Kennzeichens
 | 
						|
    for veh in EnumerateVehicles() do
 | 
						|
        local vehPlate = GetVehicleNumberPlateText(veh)
 | 
						|
        if string.gsub(vehPlate, "%s+", "") == string.gsub(plate, "%s+", "") then
 | 
						|
            DeleteRentalVehicle(veh)
 | 
						|
            print("[VehicleRental] Zusätzliches Mietfahrzeug mit Kennzeichen gelöscht: " .. plate)
 | 
						|
            break
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Regelmäßiges Update der Fahrzeugpositionen
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(30000) -- Alle 30 Sekunden
 | 
						|
        
 | 
						|
        -- Update alle aktiven Mietfahrzeuge
 | 
						|
        for plate, vehicle in pairs(activeRentalVehicles) do
 | 
						|
            if DoesEntityExist(vehicle) then
 | 
						|
                local pos = GetEntityCoords(vehicle)
 | 
						|
                local rot = GetEntityRotation(vehicle)
 | 
						|
                TriggerServerEvent('vehiclerental:server:updatePosition', plate, pos, rot)
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Wenn der Spieler das Fahrzeug verlässt, aktualisiere die Position
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(500)
 | 
						|
        
 | 
						|
        local playerPed = PlayerPedId()
 | 
						|
        local vehicle = GetVehiclePedIsIn(playerPed, true)
 | 
						|
        
 | 
						|
        if vehicle ~= 0 then
 | 
						|
            local plate = GetVehicleNumberPlateText(vehicle)
 | 
						|
            
 | 
						|
            -- Wenn es ein Mietfahrzeug ist und der Spieler es gerade verlassen hat
 | 
						|
            if activeRentalVehicles[plate] and not IsPedInVehicle(playerPed, vehicle, false) then
 | 
						|
                local pos = GetEntityCoords(vehicle)
 | 
						|
                local rot = GetEntityRotation(vehicle)
 | 
						|
                TriggerServerEvent('vehiclerental:server:updatePosition', plate, pos, rot)
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Regelmäßige Überprüfung auf "Ghost"-Mietfahrzeuge
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(300000) -- Alle 5 Minuten
 | 
						|
        
 | 
						|
        -- Hole alle aktiven Mietverhältnisse des Spielers
 | 
						|
        QBCore.Functions.TriggerCallback('vehiclerental:server:getPlayerRentals', function(rentals)
 | 
						|
            if not rentals or #rentals == 0 then return end
 | 
						|
            
 | 
						|
            local playerPos = GetEntityCoords(PlayerPedId())
 | 
						|
            local plateList = {}
 | 
						|
            
 | 
						|
            -- Erstelle Liste der gemieteten Kennzeichen
 | 
						|
            for _, rental in ipairs(rentals) do
 | 
						|
                table.insert(plateList, rental.vehicle_plate)
 | 
						|
            end
 | 
						|
            
 | 
						|
            -- Suche nach allen Fahrzeugen in der Nähe
 | 
						|
            for veh in EnumerateVehicles() do
 | 
						|
                local vehPlate = GetVehicleNumberPlateText(veh)
 | 
						|
                local vehPos = GetEntityCoords(veh)
 | 
						|
                
 | 
						|
                -- Wenn das Fahrzeug nicht in der Liste der gemieteten Fahrzeuge ist und ein RENT-Kennzeichen hat
 | 
						|
                if string.find(vehPlate, "RENT") and not activeRentalVehicles[vehPlate] then
 | 
						|
                    local isRented = false
 | 
						|
                    
 | 
						|
                    -- Prüfe, ob es in der Liste der gemieteten Fahrzeuge ist
 | 
						|
                    for _, plate in ipairs(plateList) do
 | 
						|
                        if string.gsub(vehPlate, "%s+", "") == string.gsub(plate, "%s+", "") then
 | 
						|
                            isRented = true
 | 
						|
                            activeRentalVehicles[plate] = veh -- Aktualisiere die lokale Tracking-Liste
 | 
						|
                            break
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
                    
 | 
						|
                    -- Wenn es nicht gemietet ist, aber ein RENT-Kennzeichen hat, lösche es
 | 
						|
                    if not isRented and #(playerPos - vehPos) > 100.0 then
 | 
						|
                        print("[VehicleRental] Lösche Ghost-Mietfahrzeug: " .. vehPlate)
 | 
						|
                        DeleteRentalVehicle(veh)
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end)
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Fahrzeug-Enumerator
 | 
						|
function EnumerateVehicles()
 | 
						|
    return coroutine.wrap(function()
 | 
						|
        local handle, vehicle = FindFirstVehicle()
 | 
						|
        local success
 | 
						|
        repeat
 | 
						|
            coroutine.yield(vehicle)
 | 
						|
            success, vehicle = FindNextVehicle(handle)
 | 
						|
        until not success
 | 
						|
        EndFindVehicle(handle)
 | 
						|
    end)
 | 
						|
end
 | 
						|
 | 
						|
-- Kennzeichen generieren (RENT + 4 zufällige Zeichen)
 | 
						|
function GeneratePlate()
 | 
						|
    local plate = "RENT"
 | 
						|
    for i = 1, 4 do
 | 
						|
        if math.random(1, 2) == 1 then
 | 
						|
            plate = plate .. string.char(math.random(65, 90)) -- A-Z
 | 
						|
        else
 | 
						|
            plate = plate .. tostring(math.random(0, 9)) -- 0-9
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return plate
 | 
						|
end
 | 
						|
 | 
						|
-- Cleanup beim Ressourcen-Stop
 | 
						|
AddEventHandler('onResourceStop', function(resourceName)
 | 
						|
    if GetCurrentResourceName() ~= resourceName then return end
 | 
						|
    
 | 
						|
    for _, npc in pairs(spawnedNPCs) do
 | 
						|
        if DoesEntityExist(npc) then
 | 
						|
            DeleteEntity(npc)
 | 
						|
        end
 | 
						|
    end
 | 
						|
    
 | 
						|
    for plate, vehicle in pairs(activeRentalVehicles) do
 | 
						|
        if DoesEntityExist(vehicle) then
 | 
						|
            DeleteRentalVehicle(vehicle)
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Überprüfe Mietfahrzeug-Schlüssel beim Laden des Spielers
 | 
						|
RegisterNetEvent('QBCore:Client:OnPlayerLoaded')
 | 
						|
AddEventHandler('QBCore:Client:OnPlayerLoaded', function()
 | 
						|
    TriggerServerEvent('vehiclerental:server:checkRentalKeys')
 | 
						|
end)
 |