1
0
Fork 0
forked from Simnation/Main

Update stations.lua

This commit is contained in:
Nordi98 2025-07-30 08:49:39 +02:00
parent 9f68c1ebde
commit be80d40d6d

View file

@ -257,6 +257,333 @@ function CheckAndRestoreStationVehicles()
end end
end end
-- Fortgeschrittenes Taxi-Fahrer-Verhaltenssystem
function InitializeTaxiDriverAI(driver, vehicle)
if not driver or not DoesEntityExist(driver) then return end
print("^2[TAXI STATIONS 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 STATIONS 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 STATIONS 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 STATIONS 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 STATIONS 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 STATIONS 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 STATIONS 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 STATIONS 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 STATIONS DEBUG]^7 Recovery: Path clear, continuing")
TaxiDriverContinueRoute(driver, vehicle)
else
-- Sonst versuchen zu wenden
print("^3[TAXI STATIONS 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 STATIONS 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 STATIONS 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
-- Da wir die nicht direkt auslesen können, nehmen wir an, dass es das aktuelle Ziel ist
local destination = Entity(vehicle).state.currentDestination
if destination then
-- Versuche einen alternativen Weg zu finden
print("^3[TAXI STATIONS 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 um Spieler-Sitz zu ermitteln -- Hilfsfunktion um Spieler-Sitz zu ermitteln
function GetPlayerVehicleSeat(ped, vehicle) function GetPlayerVehicleSeat(ped, vehicle)
if not IsPedInVehicle(ped, vehicle, false) then if not IsPedInVehicle(ped, vehicle, false) then
@ -311,7 +638,6 @@ RegisterNetEvent('taxi:enterStationVehicle', function(data)
-- Türen entsperren -- Türen entsperren
SetVehicleDoorsLocked(vehicle, 1) SetVehicleDoorsLocked(vehicle, 1)
-- Info-Text anzeigen während Fahrer geladen wird -- Info-Text anzeigen während Fahrer geladen wird
print("^2[TAXI STATIONS DEBUG]^7 Showing driver loading text...") print("^2[TAXI STATIONS DEBUG]^7 Showing driver loading text...")
lib.showTextUI('🚕 Warte an der Station - Fahrer wird geladen...', { lib.showTextUI('🚕 Warte an der Station - Fahrer wird geladen...', {
@ -329,7 +655,7 @@ RegisterNetEvent('taxi:enterStationVehicle', function(data)
-- Verschiedene Fahrer-Models versuchen -- Verschiedene Fahrer-Models versuchen
local driverModels = { local driverModels = {
"A_C_Chimp", -- Taxi Driver (erste Wahl) "s_m_y_taxidriver_01", -- Taxi Driver (erste Wahl)
"a_m_y_business_01", -- Business Male "a_m_y_business_01", -- Business Male
"a_m_m_business_01", -- Business Male 2 "a_m_m_business_01", -- Business Male 2
"mp_m_freemode_01", -- Male Freemode "mp_m_freemode_01", -- Male Freemode
@ -491,34 +817,20 @@ RegisterNetEvent('taxi:enterStationVehicle', function(data)
SetPedKeepTask(driver, true) SetPedKeepTask(driver, true)
SetBlockingOfNonTemporaryEvents(driver, true) SetBlockingOfNonTemporaryEvents(driver, true)
-- Verbesserte Fahrer-Einstellungen -- Fortgeschrittene KI-ähnliche Fahrer-Logik initialisieren
SetDriverAbility(driver, 1.0) -- Maximale Fahrfähigkeit local driverData = InitializeTaxiDriverAI(driver, vehicle)
SetDriverAggressiveness(driver, 0.0) -- Minimale Aggressivität
SetPedDriveByClipsetHash(driver, GetHashKey("DRIVE_SLOW"))
-- Fahrer-Outfit (nur wenn es ein anpassbarer Ped ist) -- Zufälligen Fahrer-Namen generieren
if driverHash == GetHashKey("mp_m_freemode_01") or driverHash == GetHashKey("mp_f_freemode_01") then local firstNames = {"Max", "Thomas", "Ali", "Mehmet", "Hans", "Peter", "Klaus", "Michael", "Stefan", "Frank"}
print("^2[TAXI STATIONS DEBUG]^7 Setting driver outfit...") local lastNames = {"Müller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer", "Wagner", "Becker", "Schulz", "Hoffmann"}
local driverName = firstNames[math.random(#firstNames)] .. " " .. lastNames[math.random(#lastNames)]
-- Basis-Outfit für Taxi-Fahrer -- Fahrer-Name im Fahrzeug-State speichern
SetPedComponentVariation(driver, 8, 15, 0, 0) -- Undershirt Entity(vehicle).state.driverName = driverName
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
lib.notify({ lib.notify({
title = 'Taxi Service', title = 'Taxi Service',
description = 'Fahrer bereit - Steige hinten ein', description = 'Dein Fahrer ' .. driverName .. ' ist bereit - Steige hinten ein',
type = 'success' type = 'success'
}) })
end end
@ -825,146 +1137,121 @@ function StartStationTaxiRide(stationId, vehicleId, vehicle, driver, destination
AddTextComponentString("Taxi Ziel") AddTextComponentString("Taxi Ziel")
EndTextCommandSetBlipName(destinationBlip) EndTextCommandSetBlipName(destinationBlip)
-- Zum Ziel fahren mit verbesserter Navigation und geduldiger Fahrweise -- Ziel im Fahrzeug-State speichern für die KI-Logik
-- Niedrigere Geschwindigkeit und angepasste Fahrweise Entity(vehicle).state.currentDestination = destination
local drivingStyle = 786603 -- Normal/Vorsichtig
TaskVehicleDriveToCoordLongrange(driver, vehicle, destination.x, destination.y, destination.z, 20.0, drivingStyle, 10.0)
-- Fahrt überwachen -- Zum Ziel fahren mit verbesserter Navigation
CreateThread(function() local drivingStyle = 786603 -- Normal/Vorsichtig
local lastPos = GetEntityCoords(vehicle) TaskVehicleDriveToCoordLongrange(driver, vehicle, destination.x, destination.y, destination.z, 20.0, drivingStyle, 10.0)
local stuckCounter = 0
local maxStuckCount = 20 -- Erhöht von 5 auf 20 für viel mehr Geduld
local stuckThreshold = 0.5 -- Reduziert von 1.0 auf 0.5 für genauere Erkennung
local checkInterval = 3000 -- Erhöht von 2000 auf 3000 ms für längere Prüfintervalle
local rideTimeout = GetGameTimer() + (8 * 60 * 1000) -- 8 Minuten Timeout (erhöht von 5)
local lastStuckWarning = 0 -- Zeitpunkt der letzten Steckenbleiben-Warnung
while DoesEntityExist(vehicle) and DoesEntityExist(driver) do -- Fahrer-Dialog anzeigen
local vehicleCoords = GetEntityCoords(vehicle) local driverName = Entity(vehicle).state.driverName or "Taxi-Fahrer"
local distance = #(vector3(destination.x, destination.y, destination.z) - vehicleCoords) local dialogOptions = {
local distanceMoved = #(lastPos - vehicleCoords) "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."
}
-- Überprüfen ob wir angekommen sind -- Zufälligen Dialog auswählen und anzeigen
if distance < 10.0 then Wait(3000) -- Kurz warten bevor der Fahrer spricht
-- Angekommen lib.notify({
TaskVehicleTempAction(driver, vehicle, 27, 3000) title = driverName,
description = dialogOptions[math.random(#dialogOptions)],
type = 'info',
icon = 'comment',
position = 'top-center',
duration = 5000
})
print("^2[TAXI STATIONS DEBUG]^7 Arrived at destination") -- Fahrt überwachen (vereinfacht, da KI-Logik die meiste Arbeit übernimmt)
lib.notify({ CreateThread(function()
title = 'Taxi Service', local rideTimeout = GetGameTimer() + (8 * 60 * 1000) -- 8 Minuten Timeout
description = 'Du bist angekommen! Preis: $' .. price,
type = 'success'
})
-- Bezahlung while DoesEntityExist(vehicle) and DoesEntityExist(driver) do
TriggerServerEvent('taxi:payFare', price) local vehicleCoords = GetEntityCoords(vehicle)
local distance = #(vector3(destination.x, destination.y, destination.z) - vehicleCoords)
-- Blip entfernen -- Überprüfen ob wir angekommen sind
RemoveBlip(destinationBlip) if distance < 10.0 then
-- Angekommen
TaskVehicleTempAction(driver, vehicle, 27, 3000)
-- Nach 10 Sekunden Taxi zurück zur Station print("^2[TAXI STATIONS DEBUG]^7 Arrived at destination")
SetTimeout(10000, function() lib.notify({
ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) title = 'Taxi Service',
end) description = 'Du bist angekommen! Preis: $' .. price,
type = 'success'
})
break -- Bezahlung
end TriggerServerEvent('taxi:payFare', price)
-- Überprüfen ob das Taxi stecken geblieben ist -- Blip entfernen
-- Prüfe auch ob das Fahrzeug steht (Geschwindigkeit nahe 0) RemoveBlip(destinationBlip)
local speed = GetEntitySpeed(vehicle)
local isAtRedLight = IsVehicleStoppedAtTrafficLights(vehicle)
-- Wenn das Fahrzeug an einer Ampel steht, nicht als steckengeblieben betrachten -- Fahrer-Dialog anzeigen
if distanceMoved < stuckThreshold and speed < 0.5 and not isAtRedLight then local driverName = Entity(vehicle).state.driverName or "Taxi-Fahrer"
stuckCounter = stuckCounter + 1 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 .. "."
}
-- Nur alle 5 Zähler-Erhöhungen loggen, um Spam zu vermeiden lib.notify({
if stuckCounter % 5 == 0 then title = driverName,
print("^3[TAXI STATIONS DEBUG]^7 Taxi might be stuck: " .. stuckCounter .. "/" .. maxStuckCount) description = arrivalDialogs[math.random(#arrivalDialogs)],
type = 'info',
icon = 'comment',
position = 'top-center',
duration = 5000
})
-- Nach 10 Sekunden Taxi zurück zur Station
SetTimeout(10000, function()
ReturnTaxiToStation(stationId, vehicleId, vehicle, driver)
end)
break
end end
-- Nur versuchen zu befreien, wenn wirklich lange steckengeblieben -- Überprüfen ob die Fahrt zu lange dauert
if stuckCounter >= maxStuckCount then if GetGameTimer() > rideTimeout then
-- Mindestens 30 Sekunden zwischen Befreiungsversuchen warten print("^1[TAXI STATIONS DEBUG]^7 Taxi ride timed out!")
local currentTime = GetGameTimer() lib.notify({
if currentTime - lastStuckWarning > 30000 then title = 'Taxi Service',
lastStuckWarning = currentTime description = 'Die Fahrt dauert zu lange. Wir sind fast da!',
type = 'warning'
})
print("^1[TAXI STATIONS DEBUG]^7 Taxi stuck during ride, attempting recovery") -- Teleportiere Taxi in die Nähe des Ziels
local offset = vector3(
math.random(-20, 20),
math.random(-20, 20),
0
)
local nearDestination = vector3(destination.x, destination.y, destination.z) + offset
-- Versuche, das Taxi zu befreien -- Finde gültige Z-Koordinate
ClearPedTasks(driver) local success, groundZ = GetGroundZFor_3dCoord(nearDestination.x, nearDestination.y, nearDestination.z, true)
if success then
-- Rückwärts fahren nearDestination = vector3(nearDestination.x, nearDestination.y, groundZ)
TaskVehicleTempAction(driver, vehicle, 8, 2000) -- Reverse
Wait(2000)
-- Drehen
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)
-- Neue Route zum Ziel mit geduldiger Fahrweise
local drivingStyle = 786603 -- Normal/Vorsichtig
TaskVehicleDriveToCoordLongrange(driver, vehicle, destination.x, destination.y, destination.z, 20.0, drivingStyle, 10.0)
-- Steckenbleiben-Zähler zurücksetzen, aber nicht ganz auf 0
-- So kann ein wirklich festgefahrenes Taxi nach einiger Zeit einen neuen Versuch starten
stuckCounter = maxStuckCount / 2
end end
-- Teleportiere Taxi
SetEntityCoords(vehicle, nearDestination.x, nearDestination.y, nearDestination.z, false, false, false, false)
-- Neues Timeout setzen (1 Minute)
rideTimeout = GetGameTimer() + (60 * 1000)
end end
else
-- Wenn sich das Fahrzeug bewegt oder an einer Ampel steht, Zähler langsamer reduzieren Wait(2000)
if isAtRedLight then
-- An Ampel: Zähler nicht erhöhen, aber auch nicht stark reduzieren
stuckCounter = math.max(0, stuckCounter - 0.2)
else
-- In Bewegung: Zähler reduzieren
stuckCounter = math.max(0, stuckCounter - 1)
end
end end
end)
-- Überprüfen ob die Fahrt zu lange dauert end
if GetGameTimer() > rideTimeout then
print("^1[TAXI STATIONS DEBUG]^7 Taxi ride timed out!")
lib.notify({
title = 'Taxi Service',
description = 'Die Fahrt dauert zu lange. Wir sind fast da!',
type = 'warning'
})
-- Teleportiere Taxi in die Nähe des Ziels
local offset = vector3(
math.random(-20, 20),
math.random(-20, 20),
0
)
local nearDestination = vector3(destination.x, destination.y, destination.z) + offset
-- Finde gültige Z-Koordinate
local success, groundZ = GetGroundZFor_3dCoord(nearDestination.x, nearDestination.y, nearDestination.z, true)
if success then
nearDestination = vector3(nearDestination.x, nearDestination.y, groundZ)
end
-- Teleportiere Taxi
SetEntityCoords(vehicle, nearDestination.x, nearDestination.y, nearDestination.z, false, false, false, false)
-- Neues Timeout setzen (1 Minute)
rideTimeout = GetGameTimer() + (60 * 1000)
end
lastPos = vehicleCoords
Wait(checkInterval)
end
end)
function ExitStationTaxi(stationId, vehicleId, vehicle, driver) function ExitStationTaxi(stationId, vehicleId, vehicle, driver)
print("^2[TAXI STATIONS DEBUG]^7 Player exiting station taxi") print("^2[TAXI STATIONS DEBUG]^7 Player exiting station taxi")
@ -1018,8 +1305,9 @@ function ReturnTaxiToStation(stationId, vehicleId, vehicle, driver)
-- Zufällige Position in der Nähe der Station finden -- Zufällige Position in der Nähe der Station finden
local stationCoords = Config.TaxiStations[stationId].coords local stationCoords = Config.TaxiStations[stationId].coords
-- Taxi zur Station zurückfahren lassen -- Taxi zur Station zurückfahren lassen mit geduldiger Fahrweise
TaskVehicleDriveToCoordLongrange(driver, vehicle, stationCoords.x, stationCoords.y, stationCoords.z, 25.0, 786603, 5.0) local drivingStyle = 786603 -- Normal/Vorsichtig
TaskVehicleDriveToCoordLongrange(driver, vehicle, stationCoords.x, stationCoords.y, stationCoords.z, 20.0, drivingStyle, 10.0)
-- qb-target entfernen während der Fahrt -- qb-target entfernen während der Fahrt
exports['qb-target']:RemoveTargetEntity(vehicle) exports['qb-target']:RemoveTargetEntity(vehicle)
@ -1283,3 +1571,6 @@ AddEventHandler('onResourceStop', function(resourceName)
end end
end) end)