From b70a4971fe54a8f7d99fab1e1c9be506ec553f4d Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Sat, 26 Jul 2025 02:45:59 +0200 Subject: [PATCH] Update client.lua --- .../[carscripts]/nordi_rental/client.lua | 226 +++++++++++++++++- 1 file changed, 225 insertions(+), 1 deletion(-) diff --git a/resources/[carscripts]/nordi_rental/client.lua b/resources/[carscripts]/nordi_rental/client.lua index 4c4cc6e50..499af83d0 100644 --- a/resources/[carscripts]/nordi_rental/client.lua +++ b/resources/[carscripts]/nordi_rental/client.lua @@ -1,4 +1,137 @@ --- Fahrzeug zurückgeben (GEÄNDERT - ohne im Auto zu sitzen) +local QBCore = exports['qb-core']:GetCoreObject() +local spawnedNPCs = {} +local currentRental = nil + +-- NPCs spawnen +CreateThread(function() + for i = 1, #Config.RentalLocations do + local location = Config.RentalLocations[i] + + RequestModel(location.npc.model) + while not HasModelLoaded(location.npc.model) do + Wait(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 + }, + { + type = "client", + event = "vehiclerental:client:returnVehicle", + icon = "fas fa-car-side", + label = "Fahrzeug zurückgeben", + locationId = location.id + } + }, + distance = 2.0 + }) + 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) +end + +-- Fahrzeug zurückgeben (KORRIGIERT - ohne im Auto zu sitzen) RegisterNetEvent('vehiclerental:client:returnVehicle', function(data) -- Hole alle aktiven Mietverhältnisse des Spielers QBCore.Functions.TriggerCallback('vehiclerental:server:getPlayerRentals', function(rentals) @@ -31,3 +164,94 @@ RegisterNetEvent('vehiclerental:client:returnVehicle', function(data) lib.showContext('return_vehicle_menu') end) end) + +-- Spezifisches Fahrzeug zurückgeben +function returnSpecificVehicle(plate, locationId) + -- Finde das Fahrzeug in der Nähe + local playerPos = GetEntityCoords(PlayerPedId()) + local vehicle = nil + local closestDistance = 50.0 -- Maximale Entfernung + + -- 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) + + if distance < closestDistance then + vehicle = veh + closestDistance = distance + end + end + end + + if not vehicle then + QBCore.Functions.Notify('Fahrzeug nicht in der Nähe gefunden! Bringe es zum Mietort zurück.', '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 + end + + -- Fahrzeug zurückgeben + QBCore.Functions.TriggerCallback('vehiclerental:server:returnVehicle', function(success) + if success then + DeleteVehicle(vehicle) + end + end, plate) +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 (GEÄNDERT - RENTAL + 3 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 +end)