From 7c23484c7ca47d13e08c2dceaa17544d9397eeb1 Mon Sep 17 00:00:00 2001 From: Nordi98 Date: Wed, 30 Jul 2025 02:46:15 +0200 Subject: [PATCH] ed --- resources/[tools]/nordi_taxi/client/main.lua | 88 ++- .../[tools]/nordi_taxi/client/stations.lua | 553 ++++++++++-------- 2 files changed, 383 insertions(+), 258 deletions(-) diff --git a/resources/[tools]/nordi_taxi/client/main.lua b/resources/[tools]/nordi_taxi/client/main.lua index 608569a8b..ed039e5a9 100644 --- a/resources/[tools]/nordi_taxi/client/main.lua +++ b/resources/[tools]/nordi_taxi/client/main.lua @@ -8,11 +8,16 @@ local meterRunning = false local currentFare = 0 local lastTaxiCall = 0 +print("^2[TAXI DEBUG]^7 Client script loaded") + -- Taxi rufen Command (Mobile Taxi) RegisterCommand('taxi', function() + print("^2[TAXI DEBUG]^7 /taxi command executed") + local currentTime = GetGameTimer() if currentTime - lastTaxiCall < (Config.TaxiCallCooldown * 1000) then local remainingTime = math.ceil((Config.TaxiCallCooldown * 1000 - (currentTime - lastTaxiCall)) / 1000) + print("^1[TAXI DEBUG]^7 Cooldown active: " .. remainingTime .. " seconds") lib.notify({ title = 'Taxi Service', description = 'Du musst noch ' .. remainingTime .. ' Sekunden warten', @@ -22,6 +27,7 @@ RegisterCommand('taxi', function() end if currentTaxi then + print("^1[TAXI DEBUG]^7 Taxi already exists") lib.notify({ title = 'Taxi Service', description = 'Du hast bereits ein Taxi gerufen', @@ -30,10 +36,12 @@ RegisterCommand('taxi', function() return end + print("^2[TAXI DEBUG]^7 Calling mobile taxi...") CallMobileTaxi() end) function CallMobileTaxi() + print("^2[TAXI DEBUG]^7 CallMobileTaxi function started") lastTaxiCall = GetGameTimer() lib.notify({ @@ -43,34 +51,81 @@ function CallMobileTaxi() }) CreateThread(function() + print("^2[TAXI DEBUG]^7 Taxi spawn thread started") + local playerPed = PlayerPedId() local playerCoords = GetEntityCoords(playerPed) + print("^2[TAXI DEBUG]^7 Player coords: " .. tostring(playerCoords)) + + -- Prüfe ob Config existiert + if not Config.MobileTaxiSpawns then + print("^1[TAXI DEBUG]^7 Config.MobileTaxiSpawns not found!") + return + end -- Zufällige Spawn-Location wählen local spawnLocation = Config.MobileTaxiSpawns[math.random(#Config.MobileTaxiSpawns)] + print("^2[TAXI DEBUG]^7 Spawn location: " .. tostring(spawnLocation)) -- Zufälliges Taxi-Fahrzeug wählen local selectedVehicle = SelectRandomTaxi() + print("^2[TAXI DEBUG]^7 Selected vehicle: " .. selectedVehicle.model) -- Fahrzeug spawnen local vehicleHash = GetHashKey(selectedVehicle.model) + print("^2[TAXI DEBUG]^7 Vehicle hash: " .. vehicleHash) + RequestModel(vehicleHash) - while not HasModelLoaded(vehicleHash) do + local timeout = GetGameTimer() + 10000 + while not HasModelLoaded(vehicleHash) and GetGameTimer() < timeout do + print("^3[TAXI DEBUG]^7 Waiting for model to load...") Wait(100) end + + if not HasModelLoaded(vehicleHash) then + print("^1[TAXI DEBUG]^7 Failed to load vehicle model!") + return + end + print("^2[TAXI DEBUG]^7 Creating vehicle...") currentTaxi = CreateVehicle(vehicleHash, spawnLocation.x, spawnLocation.y, spawnLocation.z, spawnLocation.w, true, false) + + if not DoesEntityExist(currentTaxi) then + print("^1[TAXI DEBUG]^7 Failed to create vehicle!") + return + end + + print("^2[TAXI DEBUG]^7 Vehicle created successfully: " .. currentTaxi) SetEntityAsMissionEntity(currentTaxi, true, true) SetVehicleOnGroundProperly(currentTaxi) -- Fahrer spawnen local driverHash = GetHashKey("a_m_m_taxi_01") RequestModel(driverHash) - while not HasModelLoaded(driverHash) do + timeout = GetGameTimer() + 10000 + while not HasModelLoaded(driverHash) and GetGameTimer() < timeout do + print("^3[TAXI DEBUG]^7 Waiting for driver model to load...") Wait(100) end + + if not HasModelLoaded(driverHash) then + print("^1[TAXI DEBUG]^7 Failed to load driver model!") + DeleteEntity(currentTaxi) + currentTaxi = nil + return + end + print("^2[TAXI DEBUG]^7 Creating driver...") taxiDriver = CreatePedInsideVehicle(currentTaxi, 26, driverHash, -1, true, false) + + if not DoesEntityExist(taxiDriver) then + print("^1[TAXI DEBUG]^7 Failed to create driver!") + DeleteEntity(currentTaxi) + currentTaxi = nil + return + end + + print("^2[TAXI DEBUG]^7 Driver created successfully: " .. taxiDriver) SetEntityAsMissionEntity(taxiDriver, true, true) SetPedFleeAttributes(taxiDriver, 0, 0) SetPedCombatAttributes(taxiDriver, 17, 1) @@ -87,15 +142,22 @@ function CallMobileTaxi() BeginTextCommandSetBlipName("STRING") AddTextComponentString("Taxi") EndTextCommandSetBlipName(taxiBlip) + print("^2[TAXI DEBUG]^7 Blip created") -- Zum Spieler fahren + print("^2[TAXI DEBUG]^7 Sending taxi to player...") TaskVehicleDriveToCoord(taxiDriver, currentTaxi, playerCoords.x, playerCoords.y, playerCoords.z, 20.0, 0, vehicleHash, 786603, 1.0, true) -- Warten bis Taxi ankommt local arrived = false - local timeout = GetGameTimer() + (Config.MaxWaitTime * 1000) + timeout = GetGameTimer() + (Config.MaxWaitTime * 1000) while not arrived and GetGameTimer() < timeout do + if not DoesEntityExist(currentTaxi) or not DoesEntityExist(taxiDriver) then + print("^1[TAXI DEBUG]^7 Taxi or driver disappeared!") + break + end + local taxiCoords = GetEntityCoords(currentTaxi) local distance = #(playerCoords - taxiCoords) @@ -103,6 +165,7 @@ function CallMobileTaxi() arrived = true TaskVehicleTempAction(taxiDriver, currentTaxi, 27, 3000) + print("^2[TAXI DEBUG]^7 Taxi arrived!") lib.notify({ title = 'Taxi Service', description = 'Dein Taxi ist angekommen! Steige ein.', @@ -115,6 +178,7 @@ function CallMobileTaxi() end if not arrived then + print("^1[TAXI DEBUG]^7 Taxi failed to arrive in time") lib.notify({ title = 'Taxi Service', description = 'Das Taxi konnte dich nicht erreichen', @@ -126,6 +190,11 @@ function CallMobileTaxi() end function SelectRandomTaxi() + if not Config.TaxiVehicles or #Config.TaxiVehicles == 0 then + print("^1[TAXI DEBUG]^7 No taxi vehicles configured!") + return {model = 'taxi', pricePerKm = 5} + end + local totalChance = 0 for _, vehicle in pairs(Config.TaxiVehicles) do totalChance = totalChance + vehicle.spawnChance @@ -145,6 +214,7 @@ function SelectRandomTaxi() end function WaitForPlayerToEnter(pricePerKm) + print("^2[TAXI DEBUG]^7 Waiting for player to enter...") CreateThread(function() local timeout = GetGameTimer() + 60000 @@ -153,6 +223,7 @@ function WaitForPlayerToEnter(pricePerKm) if IsPedInVehicle(playerPed, currentTaxi, false) then inTaxi = true + print("^2[TAXI DEBUG]^7 Player entered taxi") OpenMobileTaxiMenu(pricePerKm) break end @@ -161,6 +232,7 @@ function WaitForPlayerToEnter(pricePerKm) end if not inTaxi then + print("^1[TAXI DEBUG]^7 Player didn't enter taxi in time") lib.notify({ title = 'Taxi Service', description = 'Das Taxi ist weggefahren', @@ -172,6 +244,7 @@ function WaitForPlayerToEnter(pricePerKm) end function OpenMobileTaxiMenu(pricePerKm) + print("^2[TAXI DEBUG]^7 Opening mobile taxi menu") local options = {} -- Bekannte Ziele hinzufügen @@ -230,8 +303,12 @@ function OpenMobileTaxiMenu(pricePerKm) end function StartMobileTaxiRide(destination, price) - if not currentTaxi or not taxiDriver then return end + if not currentTaxi or not taxiDriver then + print("^1[TAXI DEBUG]^7 No taxi or driver for ride") + return + end + print("^2[TAXI DEBUG]^7 Starting taxi ride to: " .. tostring(destination)) currentFare = price meterRunning = true @@ -262,6 +339,7 @@ function StartMobileTaxiRide(destination, price) if distance < 10.0 then TaskVehicleTempAction(taxiDriver, currentTaxi, 27, 3000) + print("^2[TAXI DEBUG]^7 Arrived at destination") lib.notify({ title = 'Taxi Service', description = 'Du bist angekommen! Preis: $' .. currentFare, @@ -288,6 +366,7 @@ function CalculateDistance(coords) end function ExitMobileTaxi() + print("^2[TAXI DEBUG]^7 Player exiting taxi") local playerPed = PlayerPedId() TaskLeaveVehicle(playerPed, currentTaxi, 0) @@ -303,6 +382,7 @@ function ExitMobileTaxi() end function CleanupMobileTaxi() + print("^2[TAXI DEBUG]^7 Cleaning up mobile taxi") meterRunning = false inTaxi = false diff --git a/resources/[tools]/nordi_taxi/client/stations.lua b/resources/[tools]/nordi_taxi/client/stations.lua index 0ba0627c9..4c4156943 100644 --- a/resources/[tools]/nordi_taxi/client/stations.lua +++ b/resources/[tools]/nordi_taxi/client/stations.lua @@ -2,14 +2,28 @@ local QBCore = exports['qb-core']:GetCoreObject() local stationVehicles = {} local stationBlips = {} +print("^2[TAXI STATIONS DEBUG]^7 Stations script loaded") + -- Taxi Stationen initialisieren CreateThread(function() - Wait(1000) + Wait(2000) -- Längere Wartezeit + print("^2[TAXI STATIONS DEBUG]^7 Initializing taxi stations...") InitializeTaxiStations() end) function InitializeTaxiStations() + print("^2[TAXI STATIONS DEBUG]^7 InitializeTaxiStations started") + + if not Config.TaxiStations then + print("^1[TAXI STATIONS DEBUG]^7 Config.TaxiStations not found!") + return + end + + print("^2[TAXI STATIONS DEBUG]^7 Found " .. #Config.TaxiStations .. " stations") + for stationId, station in pairs(Config.TaxiStations) do + print("^2[TAXI STATIONS DEBUG]^7 Processing station " .. stationId .. ": " .. station.name) + -- Blip für Station erstellen local blip = AddBlipForCoord(station.blipCoords.x, station.blipCoords.y, station.blipCoords.z) SetBlipSprite(blip, 198) @@ -20,22 +34,37 @@ function InitializeTaxiStations() AddTextComponentString(station.name) EndTextCommandSetBlipName(blip) stationBlips[stationId] = blip + print("^2[TAXI STATIONS DEBUG]^7 Blip created for station " .. stationId) -- Fahrzeuge an Station spawnen stationVehicles[stationId] = {} for vehicleId, vehicleData in pairs(station.vehicles) do + print("^2[TAXI STATIONS DEBUG]^7 Spawning vehicle " .. vehicleId .. " (" .. vehicleData.model .. ") at station " .. stationId) SpawnStationVehicle(stationId, vehicleId, vehicleData) end end + + print("^2[TAXI STATIONS DEBUG]^7 All stations initialized") end function SpawnStationVehicle(stationId, vehicleId, vehicleData) + print("^2[TAXI STATIONS DEBUG]^7 SpawnStationVehicle: " .. stationId .. "/" .. vehicleId) + CreateThread(function() local vehicleHash = GetHashKey(vehicleData.model) + print("^2[TAXI STATIONS DEBUG]^7 Vehicle hash: " .. vehicleHash) + RequestModel(vehicleHash) - while not HasModelLoaded(vehicleHash) do + local timeout = GetGameTimer() + 10000 + while not HasModelLoaded(vehicleHash) and GetGameTimer() < timeout do + print("^3[TAXI STATIONS DEBUG]^7 Waiting for model " .. vehicleData.model .. " to load...") Wait(100) end + + if not HasModelLoaded(vehicleHash) then + print("^1[TAXI STATIONS DEBUG]^7 Failed to load model: " .. vehicleData.model) + return + end local vehicle = CreateVehicle( vehicleHash, @@ -47,6 +76,13 @@ function SpawnStationVehicle(stationId, vehicleId, vehicleData) false ) + if not DoesEntityExist(vehicle) then + print("^1[TAXI STATIONS DEBUG]^7 Failed to create vehicle!") + return + end + + print("^2[TAXI STATIONS DEBUG]^7 Vehicle created: " .. vehicle) + SetEntityAsMissionEntity(vehicle, true, true) SetVehicleOnGroundProperly(vehicle) SetVehicleDoorsLocked(vehicle, 2) -- Locked @@ -59,6 +95,8 @@ function SpawnStationVehicle(stationId, vehicleId, vehicleData) occupied = false } + print("^2[TAXI STATIONS DEBUG]^7 Adding qb-target for vehicle " .. vehicle) + -- qb-target für Fahrzeug hinzufügen exports['qb-target']:AddTargetEntity(vehicle, { options = { @@ -74,16 +112,22 @@ function SpawnStationVehicle(stationId, vehicleId, vehicleData) distance = 3.0 }) + print("^2[TAXI STATIONS DEBUG]^7 qb-target added for vehicle " .. vehicle) + SetModelAsNoLongerNeeded(vehicleHash) end) end -- Event für Einsteigen in Station-Taxi RegisterNetEvent('taxi:enterStationVehicle', function(data) + print("^2[TAXI STATIONS DEBUG]^7 Player trying to enter station vehicle") + print("^2[TAXI STATIONS DEBUG]^7 Data: " .. json.encode(data)) + local stationId = data.stationId local vehicleId = data.vehicleId if not stationVehicles[stationId] or not stationVehicles[stationId][vehicleId] then + print("^1[TAXI STATIONS DEBUG]^7 Vehicle not found in data") lib.notify({ title = 'Taxi Service', description = 'Dieses Taxi ist nicht verfügbar', @@ -95,6 +139,7 @@ RegisterNetEvent('taxi:enterStationVehicle', function(data) local vehicleInfo = stationVehicles[stationId][vehicleId] if vehicleInfo.occupied then + print("^1[TAXI STATIONS DEBUG]^7 Vehicle already occupied") lib.notify({ title = 'Taxi Service', description = 'Dieses Taxi ist bereits besetzt', @@ -103,6 +148,8 @@ RegisterNetEvent('taxi:enterStationVehicle', function(data) return end + print("^2[TAXI STATIONS DEBUG]^7 Entering vehicle...") + -- Spieler ins Fahrzeug setzen local playerPed = PlayerPedId() local vehicle = vehicleInfo.entity @@ -113,11 +160,26 @@ RegisterNetEvent('taxi:enterStationVehicle', function(data) -- Fahrer spawnen local driverHash = GetHashKey("a_m_m_taxi_01") RequestModel(driverHash) - while not HasModelLoaded(driverHash) do + local timeout = GetGameTimer() + 10000 + while not HasModelLoaded(driverHash) and GetGameTimer() < timeout do + print("^3[TAXI STATIONS DEBUG]^7 Waiting for driver model to load...") Wait(100) end + + if not HasModelLoaded(driverHash) then + print("^1[TAXI STATIONS DEBUG]^7 Failed to load driver model!") + return + end local driver = CreatePedInsideVehicle(vehicle, 26, driverHash, -1, true, false) + + if not DoesEntityExist(driver) then + print("^1[TAXI STATIONS DEBUG]^7 Failed to create driver!") + return + end + + print("^2[TAXI STATIONS DEBUG]^7 Driver created: " .. driver) + SetEntityAsMissionEntity(driver, true, true) SetPedFleeAttributes(driver, 0, 0) SetPedCombatAttributes(driver, 17, 1) @@ -131,272 +193,34 @@ RegisterNetEvent('taxi:enterStationVehicle', function(data) -- Warten bis Spieler eingestiegen ist CreateThread(function() - local timeout = GetGameTimer() + 10000 - while GetGameTimer() < timeout do + local enterTimeout = GetGameTimer() + 10000 + while GetGameTimer() < enterTimeout do if IsPedInVehicle(playerPed, vehicle, false) then vehicleInfo.occupied = true vehicleInfo.driver = driver + print("^2[TAXI STATIONS DEBUG]^7 Player entered, opening menu") -- Ziel-Menu öffnen OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, vehicleInfo.data.pricePerKm) break end Wait(100) end + + if not IsPedInVehicle(playerPed, vehicle, false) then + print("^1[TAXI STATIONS DEBUG]^7 Player failed to enter vehicle") + -- Cleanup + if DoesEntityExist(driver) then + DeleteEntity(driver) + end + SetVehicleDoorsLocked(vehicle, 2) + end end) end) function OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, pricePerKm) - local options = {} + print("^2[TAXI STATIONS DEBUG]^7 Opening station taxi menu") - -- Bekannte Ziele hinzufügen - for _, destination in pairs(Config.KnownDestinations) do - local customPrice = math.max(Config.MinFare, math.ceil((CalculateDistanceToCoords(destination.coords) / 1000) * pricePerKm)) - table.insert(options, { - title = destination.name, - description = 'Preis: $' .. customPrice, - icon = 'map-marker', - onSelect = function() - StartStationTaxiRide(stationId, vehicleId, vehicle, driver, destination.coords, customPrice) - end - }) - end - - -- Waypoint Option - table.insert(options, { - title = 'Zu meinem Waypoint', - description = 'Fahre zu deinem gesetzten Waypoint', - icon = 'location-dot', - onSelect = function() - local waypoint = GetFirstBlipInfoId(8) - if DoesBlipExist(waypoint) then - local coords = GetBlipInfoIdCoord(waypoint) - local distance = CalculateDistanceToCoords(coords) / 1000 - local price = math.max(Config.MinFare, math.ceil(distance * pricePerKm)) - StartStationTaxiRide(stationId, vehicleId, vehicle, driver, coords, price) - else - lib.notify({ - title = 'Taxi Service', - description = 'Du hast keinen Waypoint gesetzt', - type = 'error' - }) - OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, pricePerKm) - end - end - }) - - -- Aussteigen Option - table.insert(options, { - title = 'Aussteigen', - description = 'Das Taxi verlassen', - icon = 'door-open', - onSelect = function() - ExitStationTaxi(stationId, vehicleId, vehicle, driver) - end - }) - - lib.registerContext({ - id = 'station_taxi_menu', - title = 'Taxi - Ziel wählen', - options = options - }) - - lib.showContext('station_taxi_menu') -end - -function StartStationTaxiRide(stationId, vehicleId, vehicle, driver, destination, price) - lib.notify({ - title = 'Taxi Service', - description = 'Fahrt gestartet - Preis: $' .. price, - type = 'success' - }) - - -- Destination Blip erstellen - local destinationBlip = AddBlipForCoord(destination.x, destination.y, destination.z) - SetBlipSprite(destinationBlip, 1) - SetBlipColour(destinationBlip, 2) - SetBlipScale(destinationBlip, 0.8) - BeginTextCommandSetBlipName("STRING") - AddTextComponentString("Taxi Ziel") - EndTextCommandSetBlipName(destinationBlip) - - -- Zum Ziel fahren - TaskVehicleDriveToCoord(driver, vehicle, destination.x, destination.y, destination.z, 25.0, 0, GetEntityModel(vehicle), 786603, 1.0, true) - - -- Fahrt überwachen - CreateThread(function() - while DoesEntityExist(vehicle) and DoesEntityExist(driver) do - local vehicleCoords = GetEntityCoords(vehicle) - local distance = #(vector3(destination.x, destination.y, destination.z) - vehicleCoords) - - if distance < 10.0 then - -- Angekommen - TaskVehicleTempAction(driver, vehicle, 27, 3000) - - lib.notify({ - title = 'Taxi Service', - description = 'Du bist angekommen! Preis: $' .. price, - type = 'success' - }) - - -- Bezahlung - TriggerServerEvent('taxi:payFare', price) - - -- Blip entfernen - RemoveBlip(destinationBlip) - - -- Nach 10 Sekunden Taxi zurück zur Station - SetTimeout(10000, function() - ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) - end) - - break - end - - Wait(2000) - end - end) -end - -function ExitStationTaxi(stationId, vehicleId, vehicle, driver) - local playerPed = PlayerPedId() - TaskLeaveVehicle(playerPed, vehicle, 0) - - lib.notify({ - title = 'Taxi Service', - description = 'Du bist ausgestiegen', - type = 'info' - }) - - -- Taxi zurück zur Station nach 5 Sekunden - SetTimeout(5000, function() - ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) - end) -end - -function ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) - if not stationVehicles[stationId] or not stationVehicles[stationId][vehicleId] then - return - end - - -- Fahrer löschen - if DoesEntityExist(driver) then - DeleteEntity(driver) - end - - -- Fahrzeug löschen - if DoesEntityExist(vehicle) then - exports['qb-target']:RemoveTargetEntity(vehicle) - DeleteEntity(vehicle) - end - - -- Fahrzeug als nicht besetzt markieren - stationVehicles[stationId][vehicleId].occupied = false - stationVehicles[stationId][vehicleId].driver = nil - - -- Nach Respawn-Zeit neues Fahrzeug spawnen - SetTimeout(Config.StationTaxiRespawnTime * 1000, function() - if stationVehicles[stationId] and stationVehicles[stationId][vehicleId] then - local vehicleData = stationVehicles[stationId][vehicleId].data - SpawnStationVehicle(stationId, vehicleId, vehicleData) - end - end) -end - -function CalculateDistanceToCoords(coords) - local playerCoords = GetEntityCoords(PlayerPedId()) - return #(playerCoords - coords) -end - --- Cleanup beim Resource Stop -AddEventHandler('onResourceStop', function(resourceName) - if GetCurrentResourceName() == resourceName then - -- Alle Station-Fahrzeuge löschen - for stationId, vehicles in pairs(stationVehicles) do - for vehicleId, vehicleInfo in pairs(vehicles) do - if DoesEntityExist(vehicleInfo.entity) then - exports['qb-target']:RemoveTargetEntity(vehicleInfo.entity) - DeleteEntity(vehicleInfo.entity) - end - if vehicleInfo.driver and DoesEntityExist(vehicleInfo.driver) then - DeleteEntity(vehicleInfo.driver) - end - end - end - - -- Alle Blips entfernen - for _, blip in pairs(stationBlips) do - RemoveBlip(blip) - end - end -end) - --- Event für Admin Respawn -RegisterNetEvent('taxi:respawnAllStations', function() - -- Alle bestehenden Fahrzeuge löschen - for stationId, vehicles in pairs(stationVehicles) do - for vehicleId, vehicleInfo in pairs(vehicles) do - if DoesEntityExist(vehicleInfo.entity) then - exports['qb-target']:RemoveTargetEntity(vehicleInfo.entity) - DeleteEntity(vehicleInfo.entity) - end - if vehicleInfo.driver and DoesEntityExist(vehicleInfo.driver) then - DeleteEntity(vehicleInfo.driver) - end - end - end - - -- Stationen neu initialisieren - Wait(1000) - InitializeTaxiStations() - - lib.notify({ - title = 'Taxi Service', - description = 'Alle Taxi-Stationen wurden neu geladen', - type = 'success' - }) -end) - --- Zusätzliche Funktionen für bessere Verwaltung -function GetNearestTaxiStation() - local playerCoords = GetEntityCoords(PlayerPedId()) - local nearestStation = nil - local nearestDistance = math.huge - - for stationId, station in pairs(Config.TaxiStations) do - local distance = #(playerCoords - station.blipCoords) - if distance < nearestDistance then - nearestDistance = distance - nearestStation = {id = stationId, data = station, distance = distance} - end - end - - return nearestStation -end - --- Command um nächste Taxi-Station zu finden -RegisterCommand('nearesttaxi', function() - local nearest = GetNearestTaxiStation() - if nearest then - lib.notify({ - title = 'Taxi Service', - description = 'Nächste Station: ' .. nearest.data.name .. ' (' .. math.ceil(nearest.distance) .. 'm)', - type = 'info' - }) - - -- Waypoint zur nächsten Station setzen - SetNewWaypoint(nearest.data.blipCoords.x, nearest.data.blipCoords.y) - else - lib.notify({ - title = 'Taxi Service', - description = 'Keine Taxi-Station gefunden', - type = 'error' - }) - end -end) - --- Erweiterte Ziel-Optionen für Station-Taxis -function OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, pricePerKm) local options = {} -- Bekannte Ziele hinzufügen @@ -465,6 +289,8 @@ function OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, pricePerKm) end function OpenStationSelectionMenu(stationId, vehicleId, vehicle, driver, pricePerKm) + print("^2[TAXI STATIONS DEBUG]^7 Opening station selection menu") + local options = {} for otherStationId, station in pairs(Config.TaxiStations) do @@ -502,6 +328,198 @@ function OpenStationSelectionMenu(stationId, vehicleId, vehicle, driver, pricePe lib.showContext('station_selection_menu') end +function StartStationTaxiRide(stationId, vehicleId, vehicle, driver, destination, price) + print("^2[TAXI STATIONS DEBUG]^7 Starting station taxi ride to: " .. tostring(destination)) + + lib.notify({ + title = 'Taxi Service', + description = 'Fahrt gestartet - Preis: $' .. price, + type = 'success' + }) + + -- Destination Blip erstellen + local destinationBlip = AddBlipForCoord(destination.x, destination.y, destination.z) + SetBlipSprite(destinationBlip, 1) + SetBlipColour(destinationBlip, 2) + SetBlipScale(destinationBlip, 0.8) + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Taxi Ziel") + EndTextCommandSetBlipName(destinationBlip) + + -- Zum Ziel fahren + TaskVehicleDriveToCoord(driver, vehicle, destination.x, destination.y, destination.z, 25.0, 0, GetEntityModel(vehicle), 786603, 1.0, true) + + -- Fahrt überwachen + CreateThread(function() + while DoesEntityExist(vehicle) and DoesEntityExist(driver) do + local vehicleCoords = GetEntityCoords(vehicle) + local distance = #(vector3(destination.x, destination.y, destination.z) - vehicleCoords) + + if distance < 10.0 then + -- Angekommen + TaskVehicleTempAction(driver, vehicle, 27, 3000) + + print("^2[TAXI STATIONS DEBUG]^7 Arrived at destination") + lib.notify({ + title = 'Taxi Service', + description = 'Du bist angekommen! Preis: $' .. price, + type = 'success' + }) + + -- Bezahlung + TriggerServerEvent('taxi:payFare', price) + + -- Blip entfernen + RemoveBlip(destinationBlip) + + -- Nach 10 Sekunden Taxi zurück zur Station + SetTimeout(10000, function() + ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) + end) + + break + end + + Wait(2000) + end + end) +end + +function ExitStationTaxi(stationId, vehicleId, vehicle, driver) + print("^2[TAXI STATIONS DEBUG]^7 Player exiting station taxi") + + local playerPed = PlayerPedId() + TaskLeaveVehicle(playerPed, vehicle, 0) + + lib.notify({ + title = 'Taxi Service', + description = 'Du bist ausgestiegen', + type = 'info' + }) + + -- Taxi zurück zur Station nach 5 Sekunden + SetTimeout(5000, function() + ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) + end) +end + +function ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) + print("^2[TAXI STATIONS DEBUG]^7 Returning taxi to station: " .. stationId .. "/" .. vehicleId) + + if not stationVehicles[stationId] or not stationVehicles[stationId][vehicleId] then + print("^1[TAXI STATIONS DEBUG]^7 Station vehicle data not found for return") + return + end + + -- Fahrer löschen + if DoesEntityExist(driver) then + DeleteEntity(driver) + print("^2[TAXI STATIONS DEBUG]^7 Driver deleted") + end + + -- qb-target entfernen + if DoesEntityExist(vehicle) then + exports['qb-target']:RemoveTargetEntity(vehicle) + DeleteEntity(vehicle) + print("^2[TAXI STATIONS DEBUG]^7 Vehicle deleted") + end + + -- Fahrzeug als nicht besetzt markieren + stationVehicles[stationId][vehicleId].occupied = false + stationVehicles[stationId][vehicleId].driver = nil + stationVehicles[stationId][vehicleId].entity = nil + + -- Nach Respawn-Zeit neues Fahrzeug spawnen + print("^2[TAXI STATIONS DEBUG]^7 Scheduling respawn in " .. Config.StationTaxiRespawnTime .. " seconds") + SetTimeout(Config.StationTaxiRespawnTime * 1000, function() + if stationVehicles[stationId] and stationVehicles[stationId][vehicleId] then + local vehicleData = stationVehicles[stationId][vehicleId].data + print("^2[TAXI STATIONS DEBUG]^7 Respawning vehicle at station") + SpawnStationVehicle(stationId, vehicleId, vehicleData) + end + end) +end + +function CalculateDistanceToCoords(coords) + local playerCoords = GetEntityCoords(PlayerPedId()) + return #(playerCoords - coords) +end + +-- Zusätzliche Funktionen für bessere Verwaltung +function GetNearestTaxiStation() + local playerCoords = GetEntityCoords(PlayerPedId()) + local nearestStation = nil + local nearestDistance = math.huge + + for stationId, station in pairs(Config.TaxiStations) do + local distance = #(playerCoords - station.blipCoords) + if distance < nearestDistance then + nearestDistance = distance + nearestStation = {id = stationId, data = station, distance = distance} + end + end + + return nearestStation +end + +-- Command um nächste Taxi-Station zu finden +RegisterCommand('nearesttaxi', function() + local nearest = GetNearestTaxiStation() + if nearest then + lib.notify({ + title = 'Taxi Service', + description = 'Nächste Station: ' .. nearest.data.name .. ' (' .. math.ceil(nearest.distance) .. 'm)', + type = 'info' + }) + + -- Waypoint zur nächsten Station setzen + SetNewWaypoint(nearest.data.blipCoords.x, nearest.data.blipCoords.y) + else + lib.notify({ + title = 'Taxi Service', + description = 'Keine Taxi-Station gefunden', + type = 'error' + }) + end +end) + +-- Event für Admin Respawn +RegisterNetEvent('taxi:respawnAllStations', function() + print("^2[TAXI STATIONS DEBUG]^7 Respawning all stations...") + + -- Alle bestehenden Fahrzeuge löschen + for stationId, vehicles in pairs(stationVehicles) do + for vehicleId, vehicleInfo in pairs(vehicles) do + if vehicleInfo.entity and DoesEntityExist(vehicleInfo.entity) then + exports['qb-target']:RemoveTargetEntity(vehicleInfo.entity) + DeleteEntity(vehicleInfo.entity) + end + if vehicleInfo.driver and DoesEntityExist(vehicleInfo.driver) then + DeleteEntity(vehicleInfo.driver) + end + end + end + + -- Alle Blips entfernen + for _, blip in pairs(stationBlips) do + RemoveBlip(blip) + end + + -- Variablen zurücksetzen + stationVehicles = {} + stationBlips = {} + + -- Stationen neu initialisieren + Wait(1000) + InitializeTaxiStations() + + lib.notify({ + title = 'Taxi Service', + description = 'Alle Taxi-Stationen wurden neu geladen', + type = 'success' + }) +end) + -- Verbesserte Fahrzeug-Respawn-Logik function RespawnStationVehicle(stationId, vehicleId) if not stationVehicles[stationId] or not stationVehicles[stationId][vehicleId] then @@ -532,3 +550,30 @@ function RespawnStationVehicle(stationId, vehicleId) end) end end + +-- Cleanup beim Resource Stop +AddEventHandler('onResourceStop', function(resourceName) + if GetCurrentResourceName() == resourceName then + print("^2[TAXI STATIONS DEBUG]^7 Cleaning up stations...") + + -- Alle Station-Fahrzeuge löschen + for stationId, vehicles in pairs(stationVehicles) do + for vehicleId, vehicleInfo in pairs(vehicles) do + if vehicleInfo.entity and DoesEntityExist(vehicleInfo.entity) then + exports['qb-target']:RemoveTargetEntity(vehicleInfo.entity) + DeleteEntity(vehicleInfo.entity) + end + if vehicleInfo.driver and DoesEntityExist(vehicleInfo.driver) then + DeleteEntity(vehicleInfo.driver) + end + end + end + + -- Alle Blips entfernen + for _, blip in pairs(stationBlips) do + RemoveBlip(blip) + end + + print("^2[TAXI STATIONS DEBUG]^7 Cleanup completed") + end +end)