diff --git a/resources/[tools]/nordi_taxi/client/main.lua b/resources/[tools]/nordi_taxi/client/main.lua index ac74ef2e6..083cbb1bb 100644 --- a/resources/[tools]/nordi_taxi/client/main.lua +++ b/resources/[tools]/nordi_taxi/client/main.lua @@ -2,6 +2,7 @@ local QBCore = exports['qb-core']:GetCoreObject() local currentTaxi = nil local currentDriver = nil local taxiBlip = nil +local mapBlip = nil local destinationBlip = nil local taxiMeter = { isRunning = false, @@ -44,7 +45,7 @@ function CallTaxi() print("^2[TAXI DEBUG]^7 Player coords: " .. tostring(playerCoords)) - -- Spawn-Position für Taxi finden + -- Spawn-Position für Taxi finden - Direkt aus Config local spawnCoords = GetTaxiSpawnPosition(playerCoords) if not spawnCoords then print("^1[TAXI DEBUG]^7 No spawn position found") @@ -82,18 +83,47 @@ function CallTaxi() -- Zum Spieler fahren TaskVehicleDriveToCoord(driver, taxi, playerCoords.x, playerCoords.y, playerCoords.z, 25.0, 0, GetEntityModel(taxi), 786603, 1.0, true) - -- Blip für Taxi erstellen + -- Blip für Taxi erstellen (Entity-Blip) taxiBlip = AddBlipForEntity(taxi) SetBlipSprite(taxiBlip, 198) SetBlipColour(taxiBlip, 5) SetBlipScale(taxiBlip, 0.8) + SetBlipDisplay(taxiBlip, 2) -- Zeigt auf Minimap und großer Karte + SetBlipShowCone(taxiBlip, true) -- Zeigt Sichtkegel + SetBlipAsShortRange(taxiBlip, false) -- Immer sichtbar, egal wie weit entfernt BeginTextCommandSetBlipName("STRING") AddTextComponentString("Dein Taxi") EndTextCommandSetBlipName(taxiBlip) + -- Zusätzlicher Blip auf der Karte für bessere Sichtbarkeit + local taxiCoords = GetEntityCoords(taxi) + mapBlip = AddBlipForCoord(taxiCoords.x, taxiCoords.y, taxiCoords.z) + SetBlipSprite(mapBlip, 198) + SetBlipColour(mapBlip, 5) + SetBlipScale(mapBlip, 1.0) + SetBlipDisplay(mapBlip, 4) -- Nur auf großer Karte + BeginTextCommandSetBlipName("STRING") + AddTextComponentString("Dein Taxi") + EndTextCommandSetBlipName(mapBlip) + + -- Blip aktualisieren während Taxi unterwegs ist + CreateThread(function() + while DoesEntityExist(taxi) and mapBlip do + local taxiCoords = GetEntityCoords(taxi) + SetBlipCoords(mapBlip, taxiCoords.x, taxiCoords.y, taxiCoords.z) + Wait(1000) + end + + -- Blip entfernen wenn Thread beendet + if mapBlip then + RemoveBlip(mapBlip) + mapBlip = nil + end + end) + lib.notify({ title = 'Taxi Service', - description = 'Taxi ist unterwegs zu dir!', + description = 'Taxi ist unterwegs zu dir! Verfolge es auf der Karte.', type = 'success' }) @@ -113,74 +143,68 @@ end function GetTaxiSpawnPosition(playerCoords) print("^2[TAXI DEBUG]^7 Finding spawn position...") - local spawnDistance = 100.0 - local maxAttempts = 10 + -- Prüfen ob Config.MobileTaxiSpawns existiert und nicht leer ist + if not Config.MobileTaxiSpawns or #Config.MobileTaxiSpawns == 0 then + print("^1[TAXI DEBUG]^7 Config.MobileTaxiSpawns is missing or empty") + return nil + end - for i = 1, maxAttempts do - local angle = math.random() * 2 * math.pi - local x = playerCoords.x + math.cos(angle) * spawnDistance - local y = playerCoords.y + math.sin(angle) * spawnDistance + -- Alle Spawn-Positionen nach Entfernung sortieren + local sortedSpawns = {} + for i, spawnPos in ipairs(Config.MobileTaxiSpawns) do + local distance = #(playerCoords - vector3(spawnPos.x, spawnPos.y, spawnPos.z)) + table.insert(sortedSpawns, { + coords = spawnPos, + distance = distance + }) + end + + -- Nach Entfernung sortieren (nächste zuerst) + table.sort(sortedSpawns, function(a, b) + return a.distance < b.distance + end) + + -- Prüfen ob die nächsten Positionen frei sind + for i, spawn in ipairs(sortedSpawns) do + local spawnCoords = spawn.coords - local groundZ = 0.0 - local foundGround, z = GetGroundZFor_3dCoord(x, y, playerCoords.z + 50.0, groundZ, false) + -- Prüfen ob Position frei ist + local clearArea = true + local vehicles = GetGamePool('CVehicle') - if foundGround then - local spawnCoords = vector4(x, y, z, math.deg(angle)) - - -- Prüfen ob Position frei ist (ohne IsPositionClear) - local clearArea = true - local vehicles = GetGamePool('CVehicle') - - -- Prüfen ob andere Fahrzeuge in der Nähe sind - for _, vehicle in ipairs(vehicles) do - local vehCoords = GetEntityCoords(vehicle) - if #(vector3(x, y, z) - vehCoords) < 5.0 then - clearArea = false - break - end - end - - -- Prüfen ob Peds in der Nähe sind - if clearArea then - local peds = GetGamePool('CPed') - for _, ped in ipairs(peds) do - local pedCoords = GetEntityCoords(ped) - if #(vector3(x, y, z) - pedCoords) < 5.0 then - clearArea = false - break - end - end - end - - -- Prüfen ob Position auf einer Straße ist - if clearArea then - local isOnRoad = IsPointOnRoad(x, y, z, 0) - if isOnRoad then - print("^2[TAXI DEBUG]^7 Found spawn position at attempt " .. i) - return spawnCoords - end + -- Prüfen ob andere Fahrzeuge in der Nähe sind + for _, vehicle in ipairs(vehicles) do + local vehCoords = GetEntityCoords(vehicle) + if #(vector3(spawnCoords.x, spawnCoords.y, spawnCoords.z) - vehCoords) < 5.0 then + clearArea = false + break end end - spawnDistance = spawnDistance + 20.0 + -- Wenn Position frei ist, verwenden + if clearArea then + print("^2[TAXI DEBUG]^7 Using spawn position from config: " .. tostring(spawnCoords) .. " (Distance: " .. spawn.distance .. "m)") + return spawnCoords + end end - print("^1[TAXI DEBUG]^7 No spawn position found after " .. maxAttempts .. " attempts") - - -- Fallback: Verwende eine der vordefinierten Spawn-Positionen - if Config.MobileTaxiSpawns and #Config.MobileTaxiSpawns > 0 then - local randomSpawn = Config.MobileTaxiSpawns[math.random(#Config.MobileTaxiSpawns)] - print("^3[TAXI DEBUG]^7 Using fallback spawn position") - return randomSpawn - end - - return nil + -- Wenn keine freie Position gefunden wurde, die am weitesten entfernte verwenden + local fallbackSpawn = sortedSpawns[#sortedSpawns].coords + print("^3[TAXI DEBUG]^7 No clear spawn position found, using fallback: " .. tostring(fallbackSpawn)) + return fallbackSpawn end function SpawnTaxi(coords) print("^2[TAXI DEBUG]^7 Spawning taxi at: " .. tostring(coords)) - local taxiModel = GetHashKey(Config.TaxiVehicles[1].model) + -- Sicherstellen dass wir ein gültiges Taxi-Model haben + local taxiModel = nil + if Config.TaxiVehicles and #Config.TaxiVehicles > 0 then + taxiModel = GetHashKey(Config.TaxiVehicles[1].model) + else + taxiModel = GetHashKey("taxi") -- Fallback + end + print("^2[TAXI DEBUG]^7 Taxi model hash: " .. taxiModel) RequestModel(taxiModel) @@ -195,7 +219,23 @@ function SpawnTaxi(coords) return nil end - local taxi = CreateVehicle(taxiModel, coords.x, coords.y, coords.z, coords.w, true, false) + -- Sicherstellen dass die Z-Koordinate über dem Boden ist + local groundZ = 0.0 + local foundGround, z = GetGroundZFor_3dCoord(coords.x, coords.y, coords.z, groundZ, false) + + local finalZ = coords.z + if foundGround then + -- Sicherstellen dass wir nicht unter Wasser spawnen + local waterZ = GetWaterHeight(coords.x, coords.y, coords.z) + if waterZ > z then + print("^3[TAXI DEBUG]^7 Water detected at spawn position, adjusting height") + finalZ = waterZ + 2.0 -- 2 Meter über Wasser + else + finalZ = z + 0.5 -- 0.5 Meter über Boden + end + end + + local taxi = CreateVehicle(taxiModel, coords.x, coords.y, finalZ, coords.w, true, false) if not DoesEntityExist(taxi) then print("^1[TAXI DEBUG]^7 Failed to create taxi vehicle!") @@ -675,6 +715,11 @@ function DespawnTaxi() taxiBlip = nil end + if mapBlip then + RemoveBlip(mapBlip) + mapBlip = nil + end + if destinationBlip then RemoveBlip(destinationBlip) destinationBlip = nil @@ -696,7 +741,6 @@ function DespawnTaxi() currentTaxi = nil print("^2[TAXI DEBUG]^7 Taxi deleted") end - print("^2[TAXI DEBUG]^7 Taxi despawn completed") end) else @@ -706,6 +750,11 @@ function DespawnTaxi() taxiBlip = nil end + if mapBlip then + RemoveBlip(mapBlip) + mapBlip = nil + end + if destinationBlip then RemoveBlip(destinationBlip) destinationBlip = nil @@ -723,7 +772,6 @@ function DespawnTaxi() end end - function CalculateDistanceToCoords(coords) local playerCoords = GetEntityCoords(PlayerPedId()) return #(playerCoords - coords) @@ -755,3 +803,4 @@ AddEventHandler('onResourceStop', function(resourceName) print("^2[TAXI DEBUG]^7 Main cleanup completed") end end) +