1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-07-30 09:14:44 +02:00
parent be80d40d6d
commit 9a0756773b
2 changed files with 448 additions and 218 deletions

View file

@ -86,9 +86,6 @@ function CallTaxi()
-- Blip für Taxi erstellen (Entity-Blip)
CreateTaxiBlips(taxi)
-- Überwachung des Taxi-Fortschritts
MonitorTaxiProgress(taxi, driver, playerCoords)
-- Überwachung der Ankunft
MonitorTaxiArrival(taxi, driver, playerCoords)
@ -260,7 +257,6 @@ function GetImprovedTaxiSpawnPosition(playerCoords)
return {x = x, y = y, z = z, w = 0.0}
end
function SpawnTaxi(coords)
print("^2[TAXI DEBUG]^7 Spawning taxi at: " .. tostring(coords.x) .. ", " .. tostring(coords.y) .. ", " .. tostring(coords.z))
@ -324,6 +320,14 @@ function SpawnTaxi(coords)
SetVehicleEngineOn(taxi, true, true, false)
SetVehicleDoorsLocked(taxi, 2) -- Locked initially
-- Verbesserte Persistenz
SetEntityInvincible(taxi, true)
SetVehicleCanBeVisiblyDamaged(taxi, false)
SetEntityProofs(taxi, true, true, true, true, true, true, true, true)
SetVehicleExplodesOnHighExplosionDamage(taxi, false)
SetVehicleHasBeenOwnedByPlayer(taxi, true)
SetVehicleIsConsideredByPlayer(taxi, true)
-- Taxi-Livery setzen falls verfügbar
local liveryCount = GetVehicleLiveryCount(taxi)
if liveryCount > 0 then
@ -345,12 +349,347 @@ function SpawnTaxi(coords)
return taxi
end
-- Fortgeschrittenes Taxi-Fahrer-Verhaltenssystem
function InitializeTaxiDriverAI(driver, vehicle)
if not driver or not DoesEntityExist(driver) then return end
print("^2[TAXI DEBUG]^7 Initializing advanced taxi driver AI")
-- Fahrer-Persönlichkeit und Fähigkeiten zufällig festlegen
local driverData = {
personality = {
patience = math.random(7, 10) / 10, -- 0.7-1.0: Wie geduldig ist der Fahrer
caution = math.random(6, 10) / 10, -- 0.6-1.0: Wie vorsichtig fährt er
speedPreference = math.random(15, 25), -- 15-25: Bevorzugte Geschwindigkeit
trafficRuleCompliance = math.random(8, 10)/10 -- 0.8-1.0: Wie genau hält er Verkehrsregeln ein
},
state = {
stuckCounter = 0,
lastStuckRecovery = 0,
lastRouteRecalculation = 0,
currentBehavior = "normal", -- normal, cautious, stuck, recovery
lastSpeedCheck = 0,
speedHistory = {},
lastPositions = {},
trafficLightWaitStart = 0,
isWaitingAtTrafficLight = false
},
settings = {
maxStuckCounter = math.random(15, 25), -- Wie lange warten bis Befreiungsversuch
stuckThreshold = 0.5, -- Bewegungsschwelle für Steckenbleiben
checkInterval = 2000, -- Überprüfungsintervall in ms
positionHistorySize = 5, -- Anzahl der zu speichernden Positionen
minRecoveryInterval = 25000, -- Min. Zeit zwischen Befreiungsversuchen
minRouteRecalcInterval = 30000, -- Min. Zeit zwischen Routenneuberechnungen
trafficLightMaxWait = 45000 -- Max. Wartezeit an Ampeln
}
}
-- Fahrer-Verhalten basierend auf Persönlichkeit einstellen
SetDriverAbility(driver, driverData.personality.caution)
SetDriverAggressiveness(driver, 1.0 - driverData.personality.caution)
-- Fahrer-Daten im Entity speichern
Entity(vehicle).state.driverData = driverData
-- Fahrer-Verhalten-Thread starten
CreateThread(function()
local lastPos = GetEntityCoords(vehicle)
local lastCheck = GetGameTimer()
while DoesEntityExist(vehicle) and DoesEntityExist(driver) do
Wait(driverData.settings.checkInterval)
local currentTime = GetGameTimer()
local timeDelta = currentTime - lastCheck
lastCheck = currentTime
-- Aktuelle Position und Geschwindigkeit
local currentPos = GetEntityCoords(vehicle)
local speed = GetEntitySpeed(vehicle)
local distanceMoved = #(lastPos - currentPos)
-- Position für Historie speichern
table.insert(driverData.state.lastPositions, 1, currentPos)
if #driverData.state.lastPositions > driverData.settings.positionHistorySize then
table.remove(driverData.state.lastPositions)
end
-- Geschwindigkeit für Historie speichern
table.insert(driverData.state.speedHistory, 1, speed)
if #driverData.state.speedHistory > 5 then
table.remove(driverData.state.speedHistory)
end
-- Durchschnittsgeschwindigkeit berechnen
local avgSpeed = 0
for _, s in ipairs(driverData.state.speedHistory) do
avgSpeed = avgSpeed + s
end
avgSpeed = avgSpeed / #driverData.state.speedHistory
-- Ampel-Erkennung
local isAtTrafficLight = IsVehicleStoppedAtTrafficLights(vehicle)
-- Ampel-Wartezustand aktualisieren
if isAtTrafficLight and not driverData.state.isWaitingAtTrafficLight then
-- Gerade an Ampel angekommen
driverData.state.isWaitingAtTrafficLight = true
driverData.state.trafficLightWaitStart = currentTime
print("^3[TAXI DEBUG]^7 Taxi waiting at traffic light")
elseif isAtTrafficLight and driverData.state.isWaitingAtTrafficLight then
-- Immer noch an Ampel
local waitTime = currentTime - driverData.state.trafficLightWaitStart
-- Wenn zu lange an Ampel, versuche weiterzufahren (Ampel könnte hängen)
if waitTime > driverData.settings.trafficLightMaxWait then
print("^3[TAXI DEBUG]^7 Taxi waited too long at traffic light, trying to continue")
-- Kurz vorwärts fahren um Ampel zu überwinden
TaskVehicleTempAction(driver, vehicle, 1, 2000) -- Forward
Wait(2000)
-- Dann normale Fahrt fortsetzen
TaxiDriverContinueRoute(driver, vehicle)
driverData.state.isWaitingAtTrafficLight = false
end
elseif not isAtTrafficLight and driverData.state.isWaitingAtTrafficLight then
-- Ampel verlassen
driverData.state.isWaitingAtTrafficLight = false
print("^2[TAXI DEBUG]^7 Taxi continued after traffic light")
end
-- Steckenbleiben-Erkennung (nicht an Ampel und kaum Bewegung)
if not isAtTrafficLight and distanceMoved < driverData.settings.stuckThreshold and speed < 0.5 then
driverData.state.stuckCounter = driverData.state.stuckCounter + 1
-- Nur alle 5 Zähler-Erhöhungen loggen
if driverData.state.stuckCounter % 5 == 0 then
print("^3[TAXI DEBUG]^7 Taxi might be stuck: " .. driverData.state.stuckCounter .. "/" .. driverData.settings.maxStuckCounter)
end
-- Wenn lange genug steckengeblieben und genug Zeit seit letztem Versuch
if driverData.state.stuckCounter >= driverData.settings.maxStuckCounter and
(currentTime - driverData.state.lastStuckRecovery) > driverData.settings.minRecoveryInterval then
print("^1[TAXI DEBUG]^7 Taxi is stuck, attempting intelligent recovery")
driverData.state.lastStuckRecovery = currentTime
driverData.state.currentBehavior = "recovery"
-- Intelligente Befreiung basierend auf Umgebung
TaxiDriverIntelligentRecovery(driver, vehicle)
-- Steckenbleiben-Zähler teilweise zurücksetzen
driverData.state.stuckCounter = math.floor(driverData.settings.maxStuckCounter * 0.4)
end
else
-- Wenn sich das Fahrzeug bewegt oder an einer Ampel steht
if isAtTrafficLight then
-- An Ampel: Zähler langsamer reduzieren
driverData.state.stuckCounter = math.max(0, driverData.state.stuckCounter - 0.2)
else
-- In Bewegung: Zähler reduzieren
driverData.state.stuckCounter = math.max(0, driverData.state.stuckCounter - 1)
-- Wenn Fahrzeug sich bewegt, aber sehr langsam über längere Zeit
if avgSpeed < 2.0 and driverData.state.stuckCounter > driverData.settings.maxStuckCounter * 0.5 and
(currentTime - driverData.state.lastRouteRecalculation) > driverData.settings.minRouteRecalcInterval then
print("^3[TAXI DEBUG]^7 Taxi moving too slow, recalculating route")
driverData.state.lastRouteRecalculation = currentTime
-- Route neu berechnen
TaxiDriverRecalculateRoute(driver, vehicle)
end
end
end
-- Verhalten basierend auf Umgebung anpassen
TaxiDriverAdaptBehavior(driver, vehicle, driverData)
lastPos = currentPos
end
end)
return driverData
end
-- Intelligente Befreiung bei Steckenbleiben
function TaxiDriverIntelligentRecovery(driver, vehicle)
if not DoesEntityExist(vehicle) or not DoesEntityExist(driver) then return end
-- Aktuelle Position und Umgebung analysieren
local vehicleCoords = GetEntityCoords(vehicle)
local vehicleHeading = GetEntityHeading(vehicle)
local vehicleForwardVector = GetEntityForwardVector(vehicle)
-- Prüfen ob Hindernisse vorne, hinten, links, rechts
local forwardClear = not IsPositionOccupied(
vehicleCoords.x + vehicleForwardVector.x * 4.0,
vehicleCoords.y + vehicleForwardVector.y * 4.0,
vehicleCoords.z,
1.0, false, true, false, false, false, 0, false
)
local backwardClear = not IsPositionOccupied(
vehicleCoords.x - vehicleForwardVector.x * 4.0,
vehicleCoords.y - vehicleForwardVector.y * 4.0,
vehicleCoords.z,
1.0, false, true, false, false, false, 0, false
)
-- Befreiungsstrategie basierend auf Umgebung
ClearPedTasks(driver)
if backwardClear then
-- Rückwärts fahren wenn hinten frei
print("^3[TAXI DEBUG]^7 Recovery: Backing up")
TaskVehicleTempAction(driver, vehicle, 8, 2000) -- Reverse
Wait(2000)
if forwardClear then
-- Wenn vorne auch frei, einfach weiterfahren
print("^3[TAXI DEBUG]^7 Recovery: Path clear, continuing")
TaxiDriverContinueRoute(driver, vehicle)
else
-- Sonst versuchen zu wenden
print("^3[TAXI DEBUG]^7 Recovery: Turning around")
TaskVehicleTempAction(driver, vehicle, 7, 2000) -- Turn left
Wait(1000)
TaskVehicleTempAction(driver, vehicle, 8, 1000) -- Reverse
Wait(1000)
TaskVehicleTempAction(driver, vehicle, 6, 2000) -- Turn right
Wait(1000)
TaxiDriverContinueRoute(driver, vehicle)
end
elseif forwardClear then
-- Wenn nur vorne frei, vorwärts fahren
print("^3[TAXI DEBUG]^7 Recovery: Moving forward")
TaskVehicleTempAction(driver, vehicle, 1, 2000) -- Forward
Wait(2000)
TaxiDriverContinueRoute(driver, vehicle)
else
-- Wenn komplett eingeklemmt, versuche zu rütteln
print("^3[TAXI DEBUG]^7 Recovery: Trying to wiggle free")
TaskVehicleTempAction(driver, vehicle, 7, 1000) -- Turn left
Wait(1000)
TaskVehicleTempAction(driver, vehicle, 8, 800) -- Reverse
Wait(800)
TaskVehicleTempAction(driver, vehicle, 6, 1000) -- Turn right
Wait(1000)
TaskVehicleTempAction(driver, vehicle, 1, 800) -- Forward
Wait(800)
TaxiDriverContinueRoute(driver, vehicle)
end
end
-- Route neu berechnen
function TaxiDriverRecalculateRoute(driver, vehicle)
if not DoesEntityExist(vehicle) or not DoesEntityExist(driver) then return end
-- Aktuelle Zielposition aus dem Fahrzeug-State ermitteln
local destination = Entity(vehicle).state.currentDestination
if destination then
-- Versuche einen alternativen Weg zu finden
print("^3[TAXI DEBUG]^7 Recalculating route to destination")
-- Kurz anhalten
TaskVehicleTempAction(driver, vehicle, 27, 1000) -- Stop
Wait(1000)
-- Neue Route mit leicht geändertem Fahrstil
local drivingStyle = 786603 -- Normal/Vorsichtig
TaskVehicleDriveToCoordLongrange(driver, vehicle, destination.x, destination.y, destination.z, 20.0, drivingStyle, 10.0)
else
-- Wenn kein Ziel bekannt, einfach weiterfahren
TaxiDriverContinueRoute(driver, vehicle)
end
end
-- Normale Fahrt fortsetzen
function TaxiDriverContinueRoute(driver, vehicle)
if not DoesEntityExist(vehicle) or not DoesEntityExist(driver) then return end
-- Ziel aus dem Fahrzeug-State holen
local destination = Entity(vehicle).state.currentDestination
if destination then
-- Zum Ziel fahren mit angepasster Fahrweise
local drivingStyle = 786603 -- Normal/Vorsichtig
TaskVehicleDriveToCoordLongrange(driver, vehicle, destination.x, destination.y, destination.z, 20.0, drivingStyle, 10.0)
else
-- Wenn kein Ziel bekannt, einfach geradeaus fahren
TaskVehicleDriveWander(driver, vehicle, 15.0, 786603)
end
end
-- Fahrverhalten an Umgebung anpassen
function TaxiDriverAdaptBehavior(driver, vehicle, driverData)
if not DoesEntityExist(vehicle) or not DoesEntityExist(driver) then return end
-- Aktuelle Geschwindigkeit und Position
local speed = GetEntitySpeed(vehicle)
local vehicleCoords = GetEntityCoords(vehicle)
-- Verkehrsdichte in der Umgebung prüfen
local vehiclesNearby = 0
local vehicles = GetGamePool('CVehicle')
for _, otherVehicle in ipairs(vehicles) do
if otherVehicle ~= vehicle then
local otherCoords = GetEntityCoords(otherVehicle)
local distance = #(vehicleCoords - otherCoords)
if distance < 15.0 then
vehiclesNearby = vehiclesNearby + 1
end
end
end
-- Verhalten basierend auf Verkehrsdichte anpassen
local targetSpeed = driverData.personality.speedPreference
if vehiclesNearby > 5 then
-- Viel Verkehr: langsamer und vorsichtiger
targetSpeed = targetSpeed * 0.7
SetDriverAggressiveness(driver, 0.0)
elseif vehiclesNearby > 2 then
-- Moderater Verkehr: etwas langsamer
targetSpeed = targetSpeed * 0.85
SetDriverAggressiveness(driver, 0.1)
else
-- Wenig Verkehr: normale Geschwindigkeit
SetDriverAggressiveness(driver, 0.2)
end
-- Geschwindigkeit anpassen wenn nötig
if math.abs(speed - targetSpeed) > 5.0 then
if speed < targetSpeed then
-- Beschleunigen
TaskVehicleTempAction(driver, vehicle, 23, 500) -- Gentle forward
else
-- Abbremsen
TaskVehicleTempAction(driver, vehicle, 24, 500) -- Gentle brake
end
-- Nach der Anpassung normale Fahrt fortsetzen
Wait(500)
TaxiDriverContinueRoute(driver, vehicle)
end
end
-- Hilfsfunktion zur Normalisierung eines Vektors
function norm(vector)
local length = math.sqrt(vector.x * vector.x + vector.y * vector.y + vector.z * vector.z)
if length == 0 then
return vector3(0.0, 0.0, 0.0)
end
return vector3(vector.x / length, vector.y / length, vector.z / length)
end
function SpawnTaxiDriver(vehicle)
print("^2[TAXI DEBUG]^7 Spawning taxi driver...")
-- Bessere Fahrer-Models mit Fallbacks
local driverModels = {
"A_C_Chimp", -- Affe (erste Wahl)
"s_m_y_taxidriver_01", -- Taxi Driver (erste Wahl)
"a_m_y_business_01", -- Business Male
"a_m_m_business_01", -- Business Male 2
"mp_m_freemode_01", -- Male Freemode
@ -411,8 +750,6 @@ function SpawnTaxiDriver(vehicle)
SetEntityAsMissionEntity(driver, true, true)
SetBlockingOfNonTemporaryEvents(driver, true)
SetDriverAbility(driver, 1.0) -- Maximale Fahrfähigkeit
SetDriverAggressiveness(driver, 0.0) -- Minimale Aggressivität
SetPedFleeAttributes(driver, 0, 0)
SetPedCombatAttributes(driver, 17, 1)
SetPedSeeingRange(driver, 0.0)
@ -420,6 +757,17 @@ function SpawnTaxiDriver(vehicle)
SetPedAlertness(driver, 0)
SetPedKeepTask(driver, true)
-- Fortgeschrittene KI-ähnliche Fahrer-Logik initialisieren
local driverData = InitializeTaxiDriverAI(driver, vehicle)
-- Zufälligen Fahrer-Namen generieren
local firstNames = {"Max", "Thomas", "Ali", "Mehmet", "Hans", "Peter", "Klaus", "Michael", "Stefan", "Frank"}
local lastNames = {"Müller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer", "Wagner", "Becker", "Schulz", "Hoffmann"}
local driverName = firstNames[math.random(#firstNames)] .. " " .. lastNames[math.random(#lastNames)]
-- Fahrer-Name im Fahrzeug-State speichern
Entity(vehicle).state.driverName = driverName
-- Fahrer-Outfit (nur wenn es ein anpassbarer Ped ist)
if driverHash == GetHashKey("mp_m_freemode_01") then
print("^2[TAXI DEBUG]^7 Setting driver outfit...")
@ -494,138 +842,23 @@ end
function NavigateToPlayer(driver, taxi, playerCoords)
print("^2[TAXI DEBUG]^7 Navigating taxi to player...")
-- Ziel im Fahrzeug-State speichern für die KI-Logik
Entity(taxi).state.currentDestination = playerCoords
-- Versuche einen guten Wegpunkt in der Nähe des Spielers zu finden
local success, nodePos = GetClosestVehicleNodeWithHeading(playerCoords.x, playerCoords.y, playerCoords.z, 1, 3.0, 0)
if success then
print("^2[TAXI DEBUG]^7 Found good vehicle node near player")
-- Zum Wegpunkt fahren
TaskVehicleDriveToCoordLongrange(driver, taxi, nodePos.x, nodePos.y, nodePos.z, 25.0, 786603, 5.0)
TaskVehicleDriveToCoordLongrange(driver, taxi, nodePos.x, nodePos.y, nodePos.z, 20.0, 786603, 10.0)
else
print("^3[TAXI DEBUG]^7 No good vehicle node found, driving directly to player")
-- Direkt zum Spieler fahren
TaskVehicleDriveToCoordLongrange(driver, taxi, playerCoords.x, playerCoords.y, playerCoords.z, 25.0, 786603, 5.0)
end
-- Fahrer-Verhalten verbessern
SetDriverAggressiveness(driver, 0.0)
SetDriverAbility(driver, 1.0)
end
function MonitorTaxiProgress(taxi, driver, playerCoords)
print("^2[TAXI DEBUG]^7 Monitoring taxi progress...")
local lastPos = GetEntityCoords(taxi)
local stuckCounter = 0
local maxStuckCount = 20
local totalStuckEvents = 3
local maxTotalStuckEvents = 6
CreateThread(function()
while DoesEntityExist(taxi) and DoesEntityExist(driver) do
Wait(3000)
if not DoesEntityExist(taxi) then
print("^1[TAXI DEBUG]^7 Taxi no longer exists! Taxi ID: " .. tostring(taxi))
if currentTaxi == taxi then
print("^1[TAXI DEBUG]^7 This was the current active taxi")
else
print("^1[TAXI DEBUG]^7 This was NOT the current active taxi. Current taxi: " .. tostring(currentTaxi))
end
return
end
if not DoesEntityExist(driver) then
print("^1[TAXI DEBUG]^7 Driver no longer exists! Driver ID: " .. tostring(driver))
if currentDriver == driver then
print("^1[TAXI DEBUG]^7 This was the current active driver")
else
print("^1[TAXI DEBUG]^7 This was NOT the current active driver. Current driver: " .. tostring(currentDriver))
end
return
end
local currentPos = GetEntityCoords(taxi)
local distanceMoved = #(lastPos - currentPos)
local currentPlayerCoords = GetEntityCoords(PlayerPedId())
local distanceToPlayer = #(currentPos - currentPlayerCoords)
-- If taxi is close to player, we're done monitoring progress
if distanceToPlayer < 15.0 then
print("^2[TAXI DEBUG]^7 Taxi arrived near player, stopping progress monitoring")
return
end
-- Check if taxi is stuck (not moving much)
if distanceMoved < 1.0 then
stuckCounter = stuckCounter + 1
print("^3[TAXI DEBUG]^7 Taxi might be stuck: " .. stuckCounter .. "/" .. maxStuckCount)
-- If stuck for too long, try recovery
if stuckCounter >= maxStuckCount then
totalStuckEvents = totalStuckEvents + 1
print("^1[TAXI DEBUG]^7 Taxi is stuck, attempting recovery #" .. totalStuckEvents)
if totalStuckEvents >= maxTotalStuckEvents then
print("^1[TAXI DEBUG]^7 Too many stuck events, respawning taxi")
lib.notify({
title = 'Taxi Service',
description = 'Dein Taxi steckt fest. Ein neues wird gerufen!',
type = 'warning'
})
-- Despawn current taxi and call a new one
DespawnTaxi()
Wait(1000)
CallTaxi()
return
else
-- Try to recover
RecoverStuckTaxi(taxi, driver, currentPlayerCoords)
stuckCounter = 0
end
end
else
stuckCounter = math.max(0, stuckCounter - 1) -- Gradually reduce counter if moving
end
lastPos = currentPos
end
end)
end
function RecoverStuckTaxi(taxi, driver, playerCoords)
print("^2[TAXI DEBUG]^7 Attempting to recover stuck taxi")
-- Clear current task
ClearPedTasks(driver)
-- Try to back up a bit first
TaskVehicleTempAction(driver, taxi, 8, 2000) -- Reverse
Wait(2000)
-- Try to turn around
TaskVehicleTempAction(driver, taxi, 7, 2000) -- Turn left
Wait(1000)
TaskVehicleTempAction(driver, taxi, 8, 1000) -- Reverse
Wait(1000)
TaskVehicleTempAction(driver, taxi, 6, 2000) -- Turn right
Wait(1000)
-- Try to find a new path
local found, nodePos = GetClosestVehicleNode(playerCoords.x, playerCoords.y, playerCoords.z, 1, 3.0, 0)
if found then
print("^2[TAXI DEBUG]^7 Found new path for recovery")
TaskVehicleDriveToCoordLongrange(driver, taxi, nodePos.x, nodePos.y, nodePos.z, 25.0, 786603, 5.0)
else
-- Direct approach as fallback
print("^3[TAXI DEBUG]^7 Using direct approach for recovery")
TaskVehicleDriveToCoordLongrange(driver, taxi, playerCoords.x, playerCoords.y, playerCoords.z, 25.0, 786603, 5.0)
TaskVehicleDriveToCoordLongrange(driver, taxi, playerCoords.x, playerCoords.y, playerCoords.z, 20.0, 786603, 10.0)
end
end
function MonitorTaxiArrival(taxi, driver, playerCoords)
print("^2[TAXI DEBUG]^7 Monitoring taxi arrival...")
@ -691,8 +924,6 @@ function MonitorTaxiArrival(taxi, driver, playerCoords)
end)
end
-- Event für Einsteigen ins Taxi
RegisterNetEvent('taxi:enterTaxi', function()
print("^2[TAXI DEBUG]^7 Player entering taxi")
@ -870,48 +1101,48 @@ function StartTaxiRide(destination, price)
taxiMeter.currentFare = 0
taxiMeter.pricePerKm = Config.PricePerKm
-- Ziel im Fahrzeug-State speichern für die KI-Logik
Entity(currentTaxi).state.currentDestination = destination
-- Zum Ziel fahren mit verbesserter Navigation
NavigateToDestination(currentDriver, currentTaxi, destination)
local drivingStyle = 786603 -- Normal/Vorsichtig
TaskVehicleDriveToCoordLongrange(currentDriver, currentTaxi, destination.x, destination.y, destination.z, 20.0, drivingStyle, 10.0)
-- Fahrer-Dialog anzeigen
local driverName = Entity(currentTaxi).state.driverName or "Taxi-Fahrer"
local dialogOptions = {
"Ich bringe dich sicher ans Ziel.",
"Schönes Wetter heute, oder?",
"Ich kenne eine Abkürzung.",
"Bist du aus der Gegend?",
"Ich fahre schon seit 15 Jahren Taxi.",
"Entspann dich und genieße die Fahrt."
}
-- Zufälligen Dialog auswählen und anzeigen
Wait(3000) -- Kurz warten bevor der Fahrer spricht
lib.notify({
title = driverName,
description = dialogOptions[math.random(#dialogOptions)],
type = 'info',
icon = 'comment',
position = 'top-center',
duration = 5000
})
-- Fahrt überwachen
MonitorTaxiRide(destination, price)
end
function NavigateToDestination(driver, taxi, destination)
print("^2[TAXI DEBUG]^7 Navigating to destination...")
-- Versuche einen guten Wegpunkt in der Nähe des Ziels zu finden
local success, nodePos = GetClosestVehicleNodeWithHeading(destination.x, destination.y, destination.z, 1, 3.0, 0)
if success then
print("^2[TAXI DEBUG]^7 Found good vehicle node near destination")
-- Zum Wegpunkt fahren mit verbesserter Fahrweise
TaskVehicleDriveToCoordLongrange(driver, taxi, nodePos.x, nodePos.y, nodePos.z, 25.0, 786603, 5.0)
else
print("^3[TAXI DEBUG]^7 No good vehicle node found, driving directly to destination")
-- Direkt zum Ziel fahren
TaskVehicleDriveToCoordLongrange(driver, taxi, destination.x, destination.y, destination.z, 25.0, 786603, 5.0)
end
-- Fahrer-Verhalten verbessern
SetDriverAggressiveness(driver, 0.0)
SetDriverAbility(driver, 1.0)
end
function MonitorTaxiRide(destination, price)
print("^2[TAXI DEBUG]^7 Monitoring taxi ride...")
local lastPos = GetEntityCoords(currentTaxi)
local stuckCounter = 0
local maxStuckCount = 10
local rideTimeout = GetGameTimer() + (10 * 60 * 1000) -- 5 Minuten Timeout
local rideTimeout = GetGameTimer() + (10 * 60 * 1000) -- 10 Minuten Timeout
CreateThread(function()
while DoesEntityExist(currentTaxi) and DoesEntityExist(currentDriver) do
local taxiCoords = GetEntityCoords(currentTaxi)
local distance = #(vector3(destination.x, destination.y, destination.z) - taxiCoords)
local distanceMoved = #(lastPos - taxiCoords)
-- Überprüfen ob wir angekommen sind
if distance < 10.0 then
@ -934,6 +1165,24 @@ function MonitorTaxiRide(destination, price)
destinationBlip = nil
end
-- Fahrer-Dialog anzeigen
local driverName = Entity(currentTaxi).state.driverName or "Taxi-Fahrer"
local arrivalDialogs = {
"Wir sind da! Das macht dann $" .. price .. ".",
"Angekommen! $" .. price .. " bitte.",
"Hier sind wir. $" .. price .. ", bargeldlos ist auch möglich.",
"Ziel erreicht! Das macht $" .. price .. "."
}
lib.notify({
title = driverName,
description = arrivalDialogs[math.random(#arrivalDialogs)],
type = 'info',
icon = 'comment',
position = 'top-center',
duration = 5000
})
-- Nach 10 Sekunden Taxi despawnen
SetTimeout(10000, function()
DespawnTaxi()
@ -942,21 +1191,8 @@ function MonitorTaxiRide(destination, price)
break
end
-- Überprüfen ob das Taxi stecken geblieben ist
if distanceMoved < 1.0 then
stuckCounter = stuckCounter + 1
if stuckCounter >= maxStuckCount then
print("^1[TAXI DEBUG]^7 Taxi stuck during ride, attempting recovery")
RecoverStuckTaxi(currentTaxi, currentDriver, vector3(destination.x, destination.y, destination.z))
stuckCounter = 0
end
else
stuckCounter = math.max(0, stuckCounter - 1)
end
-- Überprüfen ob die Fahrt zu lange dauert
if GetGameTimer() > rideTimeout then
-- Überprüfen ob die Fahrt zu lange dauert
if GetGameTimer() > rideTimeout then
print("^1[TAXI DEBUG]^7 Taxi ride timed out!")
-- Berechne verbleibende Distanz
@ -995,17 +1231,13 @@ if GetGameTimer() > rideTimeout then
-- Neues Timeout setzen (2 Minuten)
rideTimeout = GetGameTimer() + (2 * 60 * 1000)
end
end
lastPos = taxiCoords
Wait(2000)
end
end)
end
function SelfDriveTaxi()
print("^2[TAXI DEBUG]^7 Player driving taxi themselves")
@ -1031,7 +1263,6 @@ function SelfDriveTaxi()
})
end
function ExitTaxi()
print("^2[TAXI DEBUG]^7 Player exiting taxi")
@ -1054,7 +1285,6 @@ function ExitTaxi()
end)
end
function DespawnTaxi()
print("^2[TAXI DEBUG]^7 Despawning taxi")
@ -1144,7 +1374,6 @@ function CalculateDistanceToCoords(coords)
return #(playerCoords - coords)
end
-- Command um Taxi zu stoppen
RegisterCommand('stoptaxi', function()
if currentTaxi and DoesEntityExist(currentTaxi) then
@ -1242,7 +1471,6 @@ function EndTaxiRide()
end)
end
-- Thread zum Überwachen des Einsteigens ins Taxi (ohne qb-target)
CreateThread(function()
while true do
@ -1270,7 +1498,6 @@ CreateThread(function()
if IsControlJustReleased(0, 38) then -- E Taste
-- Spieler will einsteigen
lib.hideTextUI()
-- Spieler hinten einsteigen lassen
local seatIndex = 1 -- Hinten links
if not IsVehicleSeatFree(currentTaxi, 1) then
@ -1317,3 +1544,6 @@ AddEventHandler('onResourceStop', function(resourceName)
print("^2[TAXI DEBUG]^7 Main cleanup completed")
end
end)

View file

@ -139,7 +139,7 @@ Config.KnownDestinations = {
},
{
name = "Paleto Bay",
coords = vector3(-276.0, 6635.0, 7.5),
coords = vector3(-296.31, 6056.98, 31.36),
price = 100
},
{