ed
This commit is contained in:
		
							parent
							
								
									19928f3c5f
								
							
						
					
					
						commit
						90ab2c2b27
					
				
					 3 changed files with 326 additions and 219 deletions
				
			
		|  | @ -1,44 +1,64 @@ | |||
| local QBCore = exports['qb-core']:GetCoreObject() | ||||
| local spawnedNPCs = {} | ||||
| local currentRental = nil | ||||
| 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) | ||||
|          | ||||
|         RequestModel(location.npc.model) | ||||
|         while not HasModelLoaded(location.npc.model) do | ||||
|             Wait(1) | ||||
|         -- Modell laden | ||||
|         RequestModel(modelHash) | ||||
|         local timeout = 0 | ||||
|         while not HasModelLoaded(modelHash) and timeout < 30 do | ||||
|             Wait(100) | ||||
|             timeout = timeout + 1 | ||||
|         end | ||||
|  | ||||
|         local npc = CreatePed(4, location.npc.model, location.npc.coords.x, location.npc.coords.y, location.npc.coords.z - 1.0, location.npc.coords.w, false, true) | ||||
|         FreezeEntityPosition(npc, true) | ||||
|         SetEntityInvincible(npc, true) | ||||
|         SetBlockingOfNonTemporaryEvents(npc, true) | ||||
|          | ||||
|         spawnedNPCs[location.id] = npc | ||||
|  | ||||
|         -- 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 | ||||
|         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 | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
|                     type = "client", | ||||
|                     event = "vehiclerental:client:returnVehicle", | ||||
|                     icon = "fas fa-car-side", | ||||
|                     label = "Fahrzeug zurückgeben", | ||||
|                     locationId = location.id | ||||
|                 } | ||||
|             }, | ||||
|             distance = 2.0 | ||||
|         }) | ||||
|                 distance = 2.0 | ||||
|             }) | ||||
|         else | ||||
|             print("Failed to load NPC model for location: " .. location.name) | ||||
|         end | ||||
|     end | ||||
| end) | ||||
|  | ||||
|  | @ -130,12 +150,18 @@ function spawnRentalVehicle(model, spawnPoint, plate) | |||
|     TriggerEvent("vehiclekeys:client:SetOwner", plate) | ||||
|     SetModelAsNoLongerNeeded(model) | ||||
|      | ||||
|     -- Registriere das Fahrzeug im Parking-System | ||||
|     TriggerEvent('vehiclerental:client:vehicleRented', vehicle, plate) | ||||
|     -- 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("Neues Mietfahrzeug erstellt: " .. plate) | ||||
| end | ||||
|  | ||||
|  | ||||
| -- Fahrzeug zurückgeben (KORRIGIERT - ohne im Auto zu sitzen) | ||||
| -- Fahrzeug zurückgeben | ||||
| RegisterNetEvent('vehiclerental:client:returnVehicle', function(data) | ||||
|     -- Hole alle aktiven Mietverhältnisse des Spielers | ||||
|     QBCore.Functions.TriggerCallback('vehiclerental:server:getPlayerRentals', function(rentals) | ||||
|  | @ -171,17 +197,33 @@ 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 playerPos = GetEntityCoords(PlayerPedId()) | ||||
|     local vehicle = nil | ||||
|     local closestDistance = 50.0 -- Maximale Entfernung | ||||
|     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 = #(playerPos - vehPos) | ||||
|             local distance = #(returnPoint - vehPos) | ||||
|              | ||||
|             if distance < closestDistance then | ||||
|                 vehicle = veh | ||||
|  | @ -191,38 +233,137 @@ function returnSpecificVehicle(plate, locationId) | |||
|     end | ||||
|  | ||||
|     if not vehicle then | ||||
|         QBCore.Functions.Notify('Fahrzeug nicht in der Nähe gefunden! Bringe es zum Mietort zurück.', 'error') | ||||
|         QBCore.Functions.Notify('Fahrzeug nicht in der Nähe des Rückgabeorts gefunden!', 'error') | ||||
|         return | ||||
|     end | ||||
|  | ||||
|     -- Prüfe ob das Fahrzeug am richtigen Ort ist | ||||
|     local location = nil | ||||
|     for i = 1, #Config.RentalLocations do | ||||
|         if Config.RentalLocations[i].id == locationId then | ||||
|             location = Config.RentalLocations[i] | ||||
|             break | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     if location then | ||||
|         local returnPos = vector3(location.returnPoint.x, location.returnPoint.y, location.returnPoint.z) | ||||
|         local vehPos = GetEntityCoords(vehicle) | ||||
|         local distance = #(returnPos - vehPos) | ||||
|          | ||||
|         if distance > 10.0 then | ||||
|             QBCore.Functions.Notify('Bringe das Fahrzeug näher zum Rückgabeort!', '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 | ||||
|             DeleteVehicle(vehicle) | ||||
|             activeRentalVehicles[plate] = nil | ||||
|             QBCore.Functions.Notify('Fahrzeug erfolgreich zurückgegeben!', 'success') | ||||
|         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 | ||||
|             DeleteVehicle(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("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] and DoesEntityExist(activeRentalVehicles[plate]) then | ||||
|         DeleteVehicle(activeRentalVehicles[plate]) | ||||
|         activeRentalVehicles[plate] = nil | ||||
|         print("Mietfahrzeug gelöscht: " .. plate) | ||||
|     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) | ||||
|  | ||||
| -- Fahrzeug-Enumerator | ||||
| function EnumerateVehicles() | ||||
|     return coroutine.wrap(function() | ||||
|  | @ -236,7 +377,7 @@ function EnumerateVehicles() | |||
|     end) | ||||
| end | ||||
|  | ||||
| -- Kennzeichen generieren (GEÄNDERT - RENTAL + 3 zufällige Zeichen) | ||||
| -- Kennzeichen generieren (RENT + 4 zufällige Zeichen) | ||||
| function GeneratePlate() | ||||
|     local plate = "RENT" | ||||
|     for i = 1, 4 do | ||||
|  | @ -258,24 +399,10 @@ AddEventHandler('onResourceStop', function(resourceName) | |||
|             DeleteEntity(npc) | ||||
|         end | ||||
|     end | ||||
| end) | ||||
| -- Integration mit mh_Parking | ||||
| RegisterNetEvent('vehiclerental:client:vehicleRented') | ||||
| AddEventHandler('vehiclerental:client:vehicleRented', function(vehicle, plate) | ||||
|     -- Warte kurz, bis das Fahrzeug vollständig gespawnt ist | ||||
|     Citizen.Wait(1000) | ||||
|      | ||||
|     -- Aktualisiere das Fahrzeug im Parking-System | ||||
|     if DoesEntityExist(vehicle) then | ||||
|         TriggerEvent("mh_Parking:updateVehicle", vehicle) | ||||
|         print("Mietfahrzeug im Parking-System registriert: " .. plate) | ||||
|     for plate, vehicle in pairs(activeRentalVehicles) do | ||||
|         if DoesEntityExist(vehicle) then | ||||
|             DeleteVehicle(vehicle) | ||||
|         end | ||||
|     end | ||||
| end) | ||||
|  | ||||
| -- Wenn ein Mietfahrzeug zurückgegeben wird | ||||
| RegisterNetEvent('vehiclerental:client:vehicleReturned') | ||||
| AddEventHandler('vehiclerental:client:vehicleReturned', function(plate) | ||||
|     -- Entferne das Fahrzeug aus dem Parking-System | ||||
|     TriggerServerEvent("mh_Parking:deleteVehicle", plate, true) | ||||
|     print("Mietfahrzeug aus dem Parking-System entfernt: " .. plate) | ||||
| end) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nordi98
						Nordi98