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")) -- Zufälligen Fahrer-Namen generieren
local firstNames = {"Max", "Thomas", "Ali", "Mehmet", "Hans", "Peter", "Klaus", "Michael", "Stefan", "Frank"}
-- Fahrer-Outfit (nur wenn es ein anpassbarer Ped ist) local lastNames = {"Müller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer", "Wagner", "Becker", "Schulz", "Hoffmann"}
if driverHash == GetHashKey("mp_m_freemode_01") or driverHash == GetHashKey("mp_f_freemode_01") then local driverName = firstNames[math.random(#firstNames)] .. " " .. lastNames[math.random(#lastNames)]
print("^2[TAXI STATIONS DEBUG]^7 Setting driver outfit...")
-- Fahrer-Name im Fahrzeug-State speichern
-- Basis-Outfit für Taxi-Fahrer Entity(vehicle).state.driverName = driverName
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
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 -- Fahrer-Dialog anzeigen
local stuckThreshold = 0.5 -- Reduziert von 1.0 auf 0.5 für genauere Erkennung local driverName = Entity(vehicle).state.driverName or "Taxi-Fahrer"
local checkInterval = 3000 -- Erhöht von 2000 auf 3000 ms für längere Prüfintervalle local dialogOptions = {
local rideTimeout = GetGameTimer() + (8 * 60 * 1000) -- 8 Minuten Timeout (erhöht von 5) "Ich bringe dich sicher ans Ziel.",
local lastStuckWarning = 0 -- Zeitpunkt der letzten Steckenbleiben-Warnung "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
})
while DoesEntityExist(vehicle) and DoesEntityExist(driver) do -- Fahrt überwachen (vereinfacht, da KI-Logik die meiste Arbeit übernimmt)
local vehicleCoords = GetEntityCoords(vehicle) CreateThread(function()
local distance = #(vector3(destination.x, destination.y, destination.z) - vehicleCoords) local rideTimeout = GetGameTimer() + (8 * 60 * 1000) -- 8 Minuten Timeout
local distanceMoved = #(lastPos - vehicleCoords)
-- Überprüfen ob wir angekommen sind while DoesEntityExist(vehicle) and DoesEntityExist(driver) do
if distance < 10.0 then local vehicleCoords = GetEntityCoords(vehicle)
-- Angekommen local distance = #(vector3(destination.x, destination.y, destination.z) - vehicleCoords)
TaskVehicleTempAction(driver, vehicle, 27, 3000)
print("^2[TAXI STATIONS DEBUG]^7 Arrived at destination") -- Überprüfen ob wir angekommen sind
lib.notify({ if distance < 10.0 then
title = 'Taxi Service', -- Angekommen
description = 'Du bist angekommen! Preis: $' .. price, TaskVehicleTempAction(driver, vehicle, 27, 3000)
type = 'success'
}) print("^2[TAXI STATIONS DEBUG]^7 Arrived at destination")
lib.notify({
-- Bezahlung title = 'Taxi Service',
TriggerServerEvent('taxi:payFare', price) description = 'Du bist angekommen! Preis: $' .. price,
type = 'success'
-- Blip entfernen })
RemoveBlip(destinationBlip)
-- Bezahlung
-- Nach 10 Sekunden Taxi zurück zur Station TriggerServerEvent('taxi:payFare', price)
SetTimeout(10000, function()
ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) -- Blip entfernen
end) RemoveBlip(destinationBlip)
break -- Fahrer-Dialog anzeigen
end local driverName = Entity(vehicle).state.driverName or "Taxi-Fahrer"
local arrivalDialogs = {
-- Überprüfen ob das Taxi stecken geblieben ist "Wir sind da! Das macht dann $" .. price .. ".",
-- Prüfe auch ob das Fahrzeug steht (Geschwindigkeit nahe 0) "Angekommen! $" .. price .. " bitte.",
local speed = GetEntitySpeed(vehicle) "Hier sind wir. $" .. price .. ", bargeldlos ist auch möglich.",
local isAtRedLight = IsVehicleStoppedAtTrafficLights(vehicle) "Ziel erreicht! Das macht $" .. price .. "."
}
-- Wenn das Fahrzeug an einer Ampel steht, nicht als steckengeblieben betrachten
if distanceMoved < stuckThreshold and speed < 0.5 and not isAtRedLight then lib.notify({
stuckCounter = stuckCounter + 1 title = driverName,
description = arrivalDialogs[math.random(#arrivalDialogs)],
-- Nur alle 5 Zähler-Erhöhungen loggen, um Spam zu vermeiden type = 'info',
if stuckCounter % 5 == 0 then icon = 'comment',
print("^3[TAXI STATIONS DEBUG]^7 Taxi might be stuck: " .. stuckCounter .. "/" .. maxStuckCount) 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") })
-- Versuche, das Taxi zu befreien -- Teleportiere Taxi in die Nähe des Ziels
ClearPedTasks(driver) local offset = vector3(
math.random(-20, 20),
-- Rückwärts fahren math.random(-20, 20),
TaskVehicleTempAction(driver, vehicle, 8, 2000) -- Reverse 0
Wait(2000) )
local nearDestination = vector3(destination.x, destination.y, destination.z) + offset
-- Drehen
TaskVehicleTempAction(driver, vehicle, 7, 2000) -- Turn left -- Finde gültige Z-Koordinate
Wait(1000) local success, groundZ = GetGroundZFor_3dCoord(nearDestination.x, nearDestination.y, nearDestination.z, true)
TaskVehicleTempAction(driver, vehicle, 8, 1000) -- Reverse if success then
Wait(1000) nearDestination = vector3(nearDestination.x, nearDestination.y, groundZ)
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)