This commit is contained in:
Nordi98 2025-07-26 03:22:23 +02:00
parent 19928f3c5f
commit 90ab2c2b27
3 changed files with 326 additions and 219 deletions

View file

@ -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)