1
0
Fork 0
forked from Simnation/Main
Main/resources/[tools]/nordi_taxi/client/main.lua

794 lines
26 KiB
Lua
Raw Normal View History

2025-07-30 02:17:38 +02:00
local QBCore = exports['qb-core']:GetCoreObject()
local currentTaxi = nil
2025-07-30 03:21:38 +02:00
local currentDriver = nil
2025-07-30 02:17:38 +02:00
local taxiBlip = nil
2025-07-30 04:08:22 +02:00
local mapBlip = nil
2025-07-30 02:17:38 +02:00
local destinationBlip = nil
2025-07-30 03:21:38 +02:00
local taxiMeter = {
isRunning = false,
startCoords = nil,
currentFare = 0,
pricePerKm = 0
}
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
print("^2[TAXI DEBUG]^7 Main script loaded")
2025-07-30 02:46:15 +02:00
2025-07-30 03:21:38 +02:00
-- Taxi rufen Command
2025-07-30 02:17:38 +02:00
RegisterCommand('taxi', function()
2025-07-30 03:21:38 +02:00
print("^2[TAXI DEBUG]^7 Taxi command executed")
2025-07-30 02:46:15 +02:00
2025-07-30 03:21:38 +02:00
if currentTaxi and DoesEntityExist(currentTaxi) then
2025-07-30 02:46:15 +02:00
print("^1[TAXI DEBUG]^7 Taxi already exists")
2025-07-30 02:17:38 +02:00
lib.notify({
title = 'Taxi Service',
description = 'Du hast bereits ein Taxi gerufen',
type = 'error'
})
return
end
2025-07-30 03:21:38 +02:00
CallTaxi()
2025-07-30 02:17:38 +02:00
end)
2025-07-30 03:21:38 +02:00
function CallTaxi()
print("^2[TAXI DEBUG]^7 CallTaxi function started")
2025-07-30 02:17:38 +02:00
lib.notify({
title = 'Taxi Service',
2025-07-30 03:21:38 +02:00
description = 'Taxi wird gerufen...',
type = 'info'
2025-07-30 02:17:38 +02:00
})
2025-07-30 03:21:38 +02:00
2025-07-30 02:17:38 +02:00
CreateThread(function()
local playerPed = PlayerPedId()
local playerCoords = GetEntityCoords(playerPed)
2025-07-30 03:21:38 +02:00
2025-07-30 02:46:15 +02:00
print("^2[TAXI DEBUG]^7 Player coords: " .. tostring(playerCoords))
2025-07-30 04:08:22 +02:00
-- Spawn-Position für Taxi finden - Direkt aus Config
2025-07-30 03:21:38 +02:00
local spawnCoords = GetTaxiSpawnPosition(playerCoords)
if not spawnCoords then
print("^1[TAXI DEBUG]^7 No spawn position found")
lib.notify({
title = 'Taxi Service',
description = 'Kein geeigneter Spawn-Punkt gefunden',
type = 'error'
})
2025-07-30 02:46:15 +02:00
return
end
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
print("^2[TAXI DEBUG]^7 Spawn coords found: " .. tostring(spawnCoords))
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
-- Taxi spawnen
local taxi = SpawnTaxi(spawnCoords)
if not taxi then
print("^1[TAXI DEBUG]^7 Failed to spawn taxi")
lib.notify({
title = 'Taxi Service',
description = 'Taxi konnte nicht gespawnt werden',
type = 'error'
})
return
2025-07-30 02:17:38 +02:00
end
2025-07-30 02:46:15 +02:00
2025-07-30 03:21:38 +02:00
print("^2[TAXI DEBUG]^7 Taxi spawned: " .. taxi)
currentTaxi = taxi
-- Fahrer spawnen
local driver = SpawnTaxiDriver(taxi)
if driver then
currentDriver = driver
print("^2[TAXI DEBUG]^7 Driver spawned: " .. driver)
-- Zum Spieler fahren
TaskVehicleDriveToCoord(driver, taxi, playerCoords.x, playerCoords.y, playerCoords.z, 25.0, 0, GetEntityModel(taxi), 786603, 1.0, true)
2025-07-30 04:08:22 +02:00
-- Blip für Taxi erstellen (Entity-Blip)
2025-07-30 03:21:38 +02:00
taxiBlip = AddBlipForEntity(taxi)
SetBlipSprite(taxiBlip, 198)
SetBlipColour(taxiBlip, 5)
SetBlipScale(taxiBlip, 0.8)
2025-07-30 04:08:22 +02:00
SetBlipDisplay(taxiBlip, 2) -- Zeigt auf Minimap und großer Karte
SetBlipShowCone(taxiBlip, true) -- Zeigt Sichtkegel
SetBlipAsShortRange(taxiBlip, false) -- Immer sichtbar, egal wie weit entfernt
2025-07-30 03:21:38 +02:00
BeginTextCommandSetBlipName("STRING")
AddTextComponentString("Dein Taxi")
EndTextCommandSetBlipName(taxiBlip)
2025-07-30 04:08:22 +02:00
-- 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)
2025-07-30 03:21:38 +02:00
lib.notify({
title = 'Taxi Service',
2025-07-30 04:08:22 +02:00
description = 'Taxi ist unterwegs zu dir! Verfolge es auf der Karte.',
2025-07-30 03:21:38 +02:00
type = 'success'
})
-- Überwachung der Ankunft
MonitorTaxiArrival(taxi, driver, playerCoords)
else
print("^1[TAXI DEBUG]^7 Failed to spawn driver")
lib.notify({
title = 'Taxi Service',
description = 'Taxi ohne Fahrer gespawnt - Du kannst es selbst fahren',
type = 'warning'
})
2025-07-30 02:46:15 +02:00
end
2025-07-30 03:21:38 +02:00
end)
end
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
function GetTaxiSpawnPosition(playerCoords)
print("^2[TAXI DEBUG]^7 Finding spawn position...")
2025-07-30 04:08:22 +02:00
-- 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
2025-07-30 03:21:38 +02:00
2025-07-30 04:08:22 +02:00
-- 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
2025-07-30 02:46:15 +02:00
2025-07-30 04:08:22 +02:00
-- Prüfen ob Position frei ist
local clearArea = true
local vehicles = GetGamePool('CVehicle')
2025-07-30 03:21:38 +02:00
2025-07-30 04:08:22 +02:00
-- 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
2025-07-30 03:21:38 +02:00
end
2025-07-30 02:46:15 +02:00
end
2025-07-30 04:08:22 +02:00
-- 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
2025-07-30 03:21:38 +02:00
end
2025-07-30 04:08:22 +02:00
-- 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
2025-07-30 03:21:38 +02:00
end
2025-07-30 03:50:38 +02:00
function SpawnTaxi(coords)
print("^2[TAXI DEBUG]^7 Spawning taxi at: " .. tostring(coords))
2025-07-30 04:08:22 +02:00
-- 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
2025-07-30 03:50:38 +02:00
print("^2[TAXI DEBUG]^7 Taxi model hash: " .. taxiModel)
RequestModel(taxiModel)
local timeout = GetGameTimer() + 10000
while not HasModelLoaded(taxiModel) and GetGameTimer() < timeout do
print("^3[TAXI DEBUG]^7 Waiting for taxi model to load...")
Wait(100)
end
if not HasModelLoaded(taxiModel) then
print("^1[TAXI DEBUG]^7 Failed to load taxi model!")
return nil
end
2025-07-30 04:35:45 +02:00
-- Direkt die Koordinaten aus der Config verwenden
local taxi = CreateVehicle(taxiModel, coords.x, coords.y, coords.z, coords.w, true, false)
2025-07-30 03:50:38 +02:00
if not DoesEntityExist(taxi) then
print("^1[TAXI DEBUG]^7 Failed to create taxi vehicle!")
return nil
end
print("^2[TAXI DEBUG]^7 Taxi created successfully: " .. taxi)
SetEntityAsMissionEntity(taxi, true, true)
SetVehicleOnGroundProperly(taxi)
SetVehicleEngineOn(taxi, true, true, false)
SetVehicleDoorsLocked(taxi, 2) -- Locked initially
-- Taxi-Livery setzen falls verfügbar
local liveryCount = GetVehicleLiveryCount(taxi)
if liveryCount > 0 then
SetVehicleLivery(taxi, 0) -- Erste Livery verwenden
print("^2[TAXI DEBUG]^7 Taxi livery set")
end
SetModelAsNoLongerNeeded(taxiModel)
return taxi
end
2025-07-30 03:38:41 +02:00
2025-07-30 04:35:45 +02:00
2025-07-30 03:21:38 +02:00
function SpawnTaxiDriver(vehicle)
print("^2[TAXI DEBUG]^7 Spawning taxi driver...")
-- Bessere Fahrer-Models mit Fallbacks
local driverModels = {
2025-07-30 03:50:38 +02:00
"mp_m_freemode_01", -- Standard Male (sollte immer verfügbar sein)
"mp_f_freemode_01", -- Standard Female
2025-07-30 03:21:38 +02:00
"a_m_y_business_01", -- Business Male
"a_f_y_business_01", -- Business Female
"a_m_m_business_01", -- Business Male 2
"a_m_y_downtown_01", -- Downtown Male
2025-07-30 03:50:38 +02:00
"s_m_m_pilot_01", -- Pilot
"s_m_y_dealer_01" -- Dealer
2025-07-30 03:21:38 +02:00
}
local driver = nil
local driverHash = nil
-- Versuche verschiedene Models
for i, modelName in pairs(driverModels) do
print("^2[TAXI DEBUG]^7 Trying driver model " .. i .. ": " .. modelName)
driverHash = GetHashKey(modelName)
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
-- Model laden
2025-07-30 02:17:38 +02:00
RequestModel(driverHash)
2025-07-30 03:21:38 +02:00
local timeout = GetGameTimer() + 8000 -- Längere Wartezeit
local attempts = 0
2025-07-30 02:46:15 +02:00
while not HasModelLoaded(driverHash) and GetGameTimer() < timeout do
2025-07-30 03:21:38 +02:00
attempts = attempts + 1
if attempts % 10 == 0 then -- Alle 1 Sekunde loggen
print("^3[TAXI DEBUG]^7 Still waiting for model " .. modelName .. " (attempt " .. attempts .. ")")
end
2025-07-30 02:17:38 +02:00
Wait(100)
end
2025-07-30 02:46:15 +02:00
2025-07-30 03:21:38 +02:00
if HasModelLoaded(driverHash) then
print("^2[TAXI DEBUG]^7 Model " .. modelName .. " loaded successfully after " .. attempts .. " attempts")
-- Fahrer erstellen
driver = CreatePedInsideVehicle(vehicle, 26, driverHash, -1, true, false)
if DoesEntityExist(driver) then
print("^2[TAXI DEBUG]^7 Driver created successfully with model: " .. modelName .. " (ID: " .. driver .. ")")
break
else
print("^1[TAXI DEBUG]^7 Failed to create driver with loaded model: " .. modelName)
SetModelAsNoLongerNeeded(driverHash)
end
else
print("^1[TAXI DEBUG]^7 Failed to load driver model: " .. modelName)
SetModelAsNoLongerNeeded(driverHash)
2025-07-30 02:46:15 +02:00
end
2025-07-30 03:21:38 +02:00
end
-- Wenn immer noch kein Fahrer erstellt wurde
if not driver or not DoesEntityExist(driver) then
print("^1[TAXI DEBUG]^7 All driver models failed, trying emergency fallback...")
2025-07-30 02:46:15 +02:00
2025-07-30 03:21:38 +02:00
-- Notfall-Fallback: Versuche den einfachsten Ped zu erstellen
local emergencyModels = {
`mp_m_freemode_01`,
`a_m_y_hipster_01`,
`a_m_m_farmer_01`,
`a_m_y_beach_01`
}
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
for _, hash in pairs(emergencyModels) do
RequestModel(hash)
local timeout = GetGameTimer() + 5000
while not HasModelLoaded(hash) and GetGameTimer() < timeout do
Wait(50)
2025-07-30 02:46:15 +02:00
end
2025-07-30 03:21:38 +02:00
if HasModelLoaded(hash) then
driver = CreatePedInsideVehicle(vehicle, 26, hash, -1, true, false)
if DoesEntityExist(driver) then
print("^2[TAXI DEBUG]^7 Emergency driver created with hash: " .. hash)
driverHash = hash
break
end
SetModelAsNoLongerNeeded(hash)
end
end
end
-- Wenn immer noch kein Fahrer
if not driver or not DoesEntityExist(driver) then
print("^1[TAXI DEBUG]^7 Could not create any driver! Continuing without driver...")
return nil
end
-- Fahrer konfigurieren
print("^2[TAXI DEBUG]^7 Configuring driver...")
SetEntityAsMissionEntity(driver, true, true)
SetPedFleeAttributes(driver, 0, 0)
SetPedCombatAttributes(driver, 17, 1)
SetPedSeeingRange(driver, 0.0)
SetPedHearingRange(driver, 0.0)
SetPedAlertness(driver, 0)
SetPedKeepTask(driver, true)
SetBlockingOfNonTemporaryEvents(driver, true)
-- Fahrer-Outfit (nur wenn es ein anpassbarer Ped ist)
if driverHash == GetHashKey("mp_m_freemode_01") or driverHash == GetHashKey("mp_f_freemode_01") then
print("^2[TAXI DEBUG]^7 Setting driver outfit...")
-- Basis-Outfit für Taxi-Fahrer
SetPedComponentVariation(driver, 8, 15, 0, 0) -- Undershirt
SetPedComponentVariation(driver, 11, 28, 0, 0) -- Jacket
SetPedComponentVariation(driver, 4, 10, 0, 0) -- Pants
SetPedComponentVariation(driver, 6, 10, 0, 0) -- Shoes
SetPedComponentVariation(driver, 1, 0, 0, 0) -- Mask
SetPedComponentVariation(driver, 3, 0, 0, 0) -- Arms
SetPedComponentVariation(driver, 5, 0, 0, 0) -- Bag
SetPedComponentVariation(driver, 7, 0, 0, 0) -- Tie
SetPedComponentVariation(driver, 9, 0, 0, 0) -- Body Armor
SetPedComponentVariation(driver, 10, 0, 0, 0) -- Decals
-- Zufällige Gesichtsmerkmale
SetPedHeadBlendData(driver, math.random(0, 20), math.random(0, 20), 0, math.random(0, 20), math.random(0, 20), 0, 0.5, 0.5, 0.0, false)
end
-- Model nicht mehr benötigt
if driverHash then
SetModelAsNoLongerNeeded(driverHash)
end
print("^2[TAXI DEBUG]^7 Driver spawn completed successfully")
return driver
end
function MonitorTaxiArrival(taxi, driver, playerCoords)
print("^2[TAXI DEBUG]^7 Monitoring taxi arrival...")
CreateThread(function()
while DoesEntityExist(taxi) and (not driver or DoesEntityExist(driver)) do
local taxiCoords = GetEntityCoords(taxi)
2025-07-30 02:17:38 +02:00
local distance = #(playerCoords - taxiCoords)
2025-07-30 03:21:38 +02:00
if distance < 15.0 then
2025-07-30 02:46:15 +02:00
print("^2[TAXI DEBUG]^7 Taxi arrived!")
2025-07-30 03:21:38 +02:00
-- Taxi stoppen
if driver and DoesEntityExist(driver) then
TaskVehicleTempAction(driver, taxi, 27, 3000) -- Brake
Wait(2000)
SetVehicleDoorsLocked(taxi, 1) -- Unlock doors
end
2025-07-30 02:17:38 +02:00
lib.notify({
title = 'Taxi Service',
description = 'Dein Taxi ist angekommen! Steige ein.',
type = 'success'
})
2025-07-30 03:21:38 +02:00
-- qb-target für Einsteigen hinzufügen
exports['qb-target']:AddTargetEntity(taxi, {
options = {
{
type = "client",
event = "taxi:enterTaxi",
icon = "fas fa-car-side",
label = "Ins Taxi einsteigen"
}
},
distance = 3.0
})
break
2025-07-30 02:17:38 +02:00
end
2025-07-30 03:21:38 +02:00
Wait(2000)
2025-07-30 02:17:38 +02:00
end
end)
end
2025-07-30 03:21:38 +02:00
-- Event für Einsteigen ins Taxi
RegisterNetEvent('taxi:enterTaxi', function()
print("^2[TAXI DEBUG]^7 Player entering taxi")
2025-07-30 02:46:15 +02:00
2025-07-30 03:21:38 +02:00
if not currentTaxi or not DoesEntityExist(currentTaxi) then
print("^1[TAXI DEBUG]^7 No taxi exists")
return
2025-07-30 02:17:38 +02:00
end
2025-07-30 03:21:38 +02:00
local playerPed = PlayerPedId()
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
-- Spieler hinten einsteigen lassen
local seatIndex = 1 -- Hinten links
if not IsVehicleSeatFree(currentTaxi, 1) then
seatIndex = 2 -- Hinten rechts
end
if not IsVehicleSeatFree(currentTaxi, seatIndex) then
seatIndex = 0 -- Beifahrer als Fallback
2025-07-30 02:17:38 +02:00
end
2025-07-30 03:21:38 +02:00
TaskEnterVehicle(playerPed, currentTaxi, 10000, seatIndex, 1.0, 1, 0)
-- Warten bis eingestiegen
2025-07-30 02:17:38 +02:00
CreateThread(function()
2025-07-30 03:21:38 +02:00
local timeout = GetGameTimer() + 10000
while GetGameTimer() < timeout do
2025-07-30 02:17:38 +02:00
if IsPedInVehicle(playerPed, currentTaxi, false) then
2025-07-30 03:21:38 +02:00
print("^2[TAXI DEBUG]^7 Player entered taxi successfully")
-- qb-target entfernen
exports['qb-target']:RemoveTargetEntity(currentTaxi)
lib.notify({
title = 'Taxi Service',
description = 'Willkommen im Taxi! Wähle dein Ziel.',
type = 'success'
})
-- Ziel-Menu öffnen
Wait(1000)
OpenDestinationMenu()
2025-07-30 02:17:38 +02:00
break
end
2025-07-30 03:21:38 +02:00
Wait(100)
2025-07-30 02:17:38 +02:00
end
end)
2025-07-30 03:21:38 +02:00
end)
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
function OpenDestinationMenu()
print("^2[TAXI DEBUG]^7 Opening destination menu")
2025-07-30 02:17:38 +02:00
local options = {}
-- Bekannte Ziele hinzufügen
for _, destination in pairs(Config.KnownDestinations) do
2025-07-30 03:21:38 +02:00
local distance = CalculateDistanceToCoords(destination.coords) / 1000 -- in km
local price = math.max(Config.MinFare, math.ceil(distance * Config.PricePerKm))
2025-07-30 02:17:38 +02:00
table.insert(options, {
title = destination.name,
2025-07-30 03:21:38 +02:00
description = 'Preis: $' .. price .. ' | Entfernung: ' .. math.ceil(distance * 100) / 100 .. 'km',
2025-07-30 02:17:38 +02:00
icon = 'map-marker',
onSelect = function()
2025-07-30 03:21:38 +02:00
StartTaxiRide(destination.coords, price)
2025-07-30 02:17:38 +02:00
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)
2025-07-30 03:21:38 +02:00
local distance = CalculateDistanceToCoords(coords) / 1000
local price = math.max(Config.MinFare, math.ceil(distance * Config.PricePerKm))
StartTaxiRide(coords, price)
2025-07-30 02:17:38 +02:00
else
lib.notify({
title = 'Taxi Service',
description = 'Du hast keinen Waypoint gesetzt',
type = 'error'
})
2025-07-30 03:21:38 +02:00
OpenDestinationMenu()
2025-07-30 02:17:38 +02:00
end
end
})
2025-07-30 03:21:38 +02:00
-- Selbst fahren Option (wenn kein Fahrer)
if not currentDriver or not DoesEntityExist(currentDriver) then
table.insert(options, {
title = '🚗 Selbst fahren',
description = 'Du fährst das Taxi selbst',
icon = 'car',
onSelect = function()
SelfDriveTaxi()
end
})
end
2025-07-30 02:17:38 +02:00
-- Aussteigen Option
table.insert(options, {
title = 'Aussteigen',
description = 'Das Taxi verlassen',
icon = 'door-open',
onSelect = function()
2025-07-30 03:21:38 +02:00
ExitTaxi()
2025-07-30 02:17:38 +02:00
end
})
lib.registerContext({
2025-07-30 03:21:38 +02:00
id = 'taxi_destination_menu',
2025-07-30 02:17:38 +02:00
title = 'Taxi - Ziel wählen',
options = options
})
2025-07-30 03:21:38 +02:00
lib.showContext('taxi_destination_menu')
2025-07-30 02:17:38 +02:00
end
2025-07-30 03:21:38 +02:00
function StartTaxiRide(destination, price)
print("^2[TAXI DEBUG]^7 Starting taxi ride to: " .. tostring(destination))
if not currentTaxi or not DoesEntityExist(currentTaxi) then
print("^1[TAXI DEBUG]^7 No taxi exists for ride")
return
2025-07-30 02:46:15 +02:00
end
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
-- Wenn kein Fahrer, Spieler selbst fahren lassen
if not currentDriver or not DoesEntityExist(currentDriver) then
lib.notify({
title = 'Taxi Service',
description = 'Kein Fahrer verfügbar. Du musst selbst fahren!',
type = 'warning'
})
return
end
lib.notify({
title = 'Taxi Service',
description = 'Fahrt gestartet - Preis: $' .. price,
type = 'success'
})
2025-07-30 02:17:38 +02:00
-- Destination Blip erstellen
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
2025-07-30 03:21:38 +02:00
TaskVehicleDriveToCoord(currentDriver, currentTaxi, destination.x, destination.y, destination.z, 25.0, 0, GetEntityModel(currentTaxi), 786603, 1.0, true)
-- Fahrt überwachen
MonitorTaxiRide(destination, price)
end
function MonitorTaxiRide(destination, price)
print("^2[TAXI DEBUG]^7 Monitoring taxi ride...")
2025-07-30 02:17:38 +02:00
CreateThread(function()
2025-07-30 03:21:38 +02:00
while DoesEntityExist(currentTaxi) and DoesEntityExist(currentDriver) do
2025-07-30 02:17:38 +02:00
local taxiCoords = GetEntityCoords(currentTaxi)
local distance = #(vector3(destination.x, destination.y, destination.z) - taxiCoords)
if distance < 10.0 then
2025-07-30 03:21:38 +02:00
-- Angekommen
TaskVehicleTempAction(currentDriver, currentTaxi, 27, 3000)
2025-07-30 02:17:38 +02:00
2025-07-30 02:46:15 +02:00
print("^2[TAXI DEBUG]^7 Arrived at destination")
2025-07-30 02:17:38 +02:00
lib.notify({
title = 'Taxi Service',
2025-07-30 03:21:38 +02:00
description = 'Du bist angekommen! Preis: $' .. price,
2025-07-30 02:17:38 +02:00
type = 'success'
})
2025-07-30 03:21:38 +02:00
-- Bezahlung
TriggerServerEvent('taxi:payFare', price)
2025-07-30 02:17:38 +02:00
2025-07-30 03:21:38 +02:00
-- Blips entfernen
if destinationBlip then
RemoveBlip(destinationBlip)
destinationBlip = nil
end
-- Nach 10 Sekunden Taxi despawnen
2025-07-30 02:17:38 +02:00
SetTimeout(10000, function()
2025-07-30 03:21:38 +02:00
DespawnTaxi()
2025-07-30 02:17:38 +02:00
end)
break
end
Wait(2000)
end
end)
end
2025-07-30 03:21:38 +02:00
function SelfDriveTaxi()
print("^2[TAXI DEBUG]^7 Player driving taxi themselves")
if not currentTaxi or not DoesEntityExist(currentTaxi) then
return
end
local playerPed = PlayerPedId()
-- Fahrer entfernen falls vorhanden
if currentDriver and DoesEntityExist(currentDriver) then
DeleteEntity(currentDriver)
currentDriver = nil
end
-- Spieler zum Fahrersitz bewegen
TaskShuffleToNextVehicleSeat(playerPed, currentTaxi)
lib.notify({
title = 'Taxi Service',
description = 'Du fährst das Taxi jetzt selbst. Nutze /stoptaxi um es zu beenden.',
type = 'info'
})
2025-07-30 02:17:38 +02:00
end
2025-07-30 03:21:38 +02:00
function ExitTaxi()
2025-07-30 02:46:15 +02:00
print("^2[TAXI DEBUG]^7 Player exiting taxi")
2025-07-30 03:21:38 +02:00
if not currentTaxi or not DoesEntityExist(currentTaxi) then
return
end
2025-07-30 02:17:38 +02:00
local playerPed = PlayerPedId()
TaskLeaveVehicle(playerPed, currentTaxi, 0)
lib.notify({
title = 'Taxi Service',
description = 'Du bist ausgestiegen',
type = 'info'
})
2025-07-30 03:21:38 +02:00
-- Taxi nach 5 Sekunden despawnen
2025-07-30 02:17:38 +02:00
SetTimeout(5000, function()
2025-07-30 03:21:38 +02:00
DespawnTaxi()
2025-07-30 02:17:38 +02:00
end)
end
2025-07-30 03:21:38 +02:00
function DespawnTaxi()
print("^2[TAXI DEBUG]^7 Despawning taxi")
2025-07-30 02:17:38 +02:00
2025-07-30 03:50:38 +02:00
if not currentTaxi or not DoesEntityExist(currentTaxi) then
return
2025-07-30 02:17:38 +02:00
end
2025-07-30 03:50:38 +02:00
-- Taxi wegfahren lassen, wenn ein Fahrer existiert
if currentDriver and DoesEntityExist(currentDriver) then
print("^2[TAXI DEBUG]^7 Making taxi drive away before despawn")
-- Zufällige Position in der Nähe finden
local taxiCoords = GetEntityCoords(currentTaxi)
local angle = math.random() * 2 * math.pi
local distance = 150.0
local driveToX = taxiCoords.x + math.cos(angle) * distance
local driveToY = taxiCoords.y + math.sin(angle) * distance
-- Taxi wegfahren lassen
TaskVehicleDriveToCoord(currentDriver, currentTaxi, driveToX, driveToY, taxiCoords.z, 25.0, 0, GetEntityModel(currentTaxi), 786603, 1.0, true)
-- Blips entfernen
if taxiBlip then
RemoveBlip(taxiBlip)
taxiBlip = nil
end
2025-07-30 04:08:22 +02:00
if mapBlip then
RemoveBlip(mapBlip)
mapBlip = nil
end
2025-07-30 03:50:38 +02:00
if destinationBlip then
RemoveBlip(destinationBlip)
destinationBlip = nil
2025-07-30 03:54:22 +02:00
end
2025-07-30 03:50:38 +02:00
-- Nach 10 Sekunden tatsächlich löschen
SetTimeout(10000, function()
-- Fahrer löschen
if currentDriver and DoesEntityExist(currentDriver) then
DeleteEntity(currentDriver)
currentDriver = nil
print("^2[TAXI DEBUG]^7 Driver deleted")
end
-- Taxi löschen
if currentTaxi and DoesEntityExist(currentTaxi) then
exports['qb-target']:RemoveTargetEntity(currentTaxi)
DeleteEntity(currentTaxi)
currentTaxi = nil
print("^2[TAXI DEBUG]^7 Taxi deleted")
end
print("^2[TAXI DEBUG]^7 Taxi despawn completed")
end)
else
-- Sofort löschen wenn kein Fahrer da ist
if taxiBlip then
RemoveBlip(taxiBlip)
taxiBlip = nil
end
2025-07-30 04:08:22 +02:00
if mapBlip then
RemoveBlip(mapBlip)
mapBlip = nil
end
2025-07-30 03:50:38 +02:00
if destinationBlip then
RemoveBlip(destinationBlip)
destinationBlip = nil
2025-07-30 03:54:22 +02:00
end
2025-07-30 03:50:38 +02:00
-- Taxi löschen
if currentTaxi and DoesEntityExist(currentTaxi) then
exports['qb-target']:RemoveTargetEntity(currentTaxi)
DeleteEntity(currentTaxi)
currentTaxi = nil
print("^2[TAXI DEBUG]^7 Taxi deleted")
end
print("^2[TAXI DEBUG]^7 Taxi despawn completed (no driver)")
2025-07-30 02:17:38 +02:00
end
2025-07-30 03:54:22 +02:00
end
2025-07-30 03:21:38 +02:00
function CalculateDistanceToCoords(coords)
local playerCoords = GetEntityCoords(PlayerPedId())
return #(playerCoords - coords)
end
-- Command um Taxi zu stoppen
RegisterCommand('stoptaxi', function()
if currentTaxi and DoesEntityExist(currentTaxi) then
DespawnTaxi()
lib.notify({
title = 'Taxi Service',
description = 'Taxi-Service beendet',
type = 'info'
})
else
lib.notify({
title = 'Taxi Service',
description = 'Du hast kein aktives Taxi',
type = 'error'
})
2025-07-30 02:17:38 +02:00
end
end)
2025-07-30 03:21:38 +02:00
-- Cleanup beim Resource Stop
2025-07-30 02:17:38 +02:00
AddEventHandler('onResourceStop', function(resourceName)
if GetCurrentResourceName() == resourceName then
2025-07-30 03:21:38 +02:00
print("^2[TAXI DEBUG]^7 Cleaning up main script...")
DespawnTaxi()
print("^2[TAXI DEBUG]^7 Main cleanup completed")
2025-07-30 02:17:38 +02:00
end
end)
2025-07-30 04:08:22 +02:00