forked from Simnation/Main
ed
This commit is contained in:
parent
be80d40d6d
commit
9a0756773b
2 changed files with 448 additions and 218 deletions
|
@ -86,9 +86,6 @@ function CallTaxi()
|
||||||
-- Blip für Taxi erstellen (Entity-Blip)
|
-- Blip für Taxi erstellen (Entity-Blip)
|
||||||
CreateTaxiBlips(taxi)
|
CreateTaxiBlips(taxi)
|
||||||
|
|
||||||
-- Überwachung des Taxi-Fortschritts
|
|
||||||
MonitorTaxiProgress(taxi, driver, playerCoords)
|
|
||||||
|
|
||||||
-- Überwachung der Ankunft
|
-- Überwachung der Ankunft
|
||||||
MonitorTaxiArrival(taxi, driver, playerCoords)
|
MonitorTaxiArrival(taxi, driver, playerCoords)
|
||||||
|
|
||||||
|
@ -260,7 +257,6 @@ function GetImprovedTaxiSpawnPosition(playerCoords)
|
||||||
return {x = x, y = y, z = z, w = 0.0}
|
return {x = x, y = y, z = z, w = 0.0}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function SpawnTaxi(coords)
|
function SpawnTaxi(coords)
|
||||||
print("^2[TAXI DEBUG]^7 Spawning taxi at: " .. tostring(coords.x) .. ", " .. tostring(coords.y) .. ", " .. tostring(coords.z))
|
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)
|
SetVehicleEngineOn(taxi, true, true, false)
|
||||||
SetVehicleDoorsLocked(taxi, 2) -- Locked initially
|
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
|
-- Taxi-Livery setzen falls verfügbar
|
||||||
local liveryCount = GetVehicleLiveryCount(taxi)
|
local liveryCount = GetVehicleLiveryCount(taxi)
|
||||||
if liveryCount > 0 then
|
if liveryCount > 0 then
|
||||||
|
@ -345,12 +349,347 @@ function SpawnTaxi(coords)
|
||||||
return taxi
|
return taxi
|
||||||
end
|
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)
|
function SpawnTaxiDriver(vehicle)
|
||||||
print("^2[TAXI DEBUG]^7 Spawning taxi driver...")
|
print("^2[TAXI DEBUG]^7 Spawning taxi driver...")
|
||||||
|
|
||||||
-- Bessere Fahrer-Models mit Fallbacks
|
-- Bessere Fahrer-Models mit Fallbacks
|
||||||
local driverModels = {
|
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_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
|
||||||
|
@ -411,8 +750,6 @@ function SpawnTaxiDriver(vehicle)
|
||||||
|
|
||||||
SetEntityAsMissionEntity(driver, true, true)
|
SetEntityAsMissionEntity(driver, true, true)
|
||||||
SetBlockingOfNonTemporaryEvents(driver, true)
|
SetBlockingOfNonTemporaryEvents(driver, true)
|
||||||
SetDriverAbility(driver, 1.0) -- Maximale Fahrfähigkeit
|
|
||||||
SetDriverAggressiveness(driver, 0.0) -- Minimale Aggressivität
|
|
||||||
SetPedFleeAttributes(driver, 0, 0)
|
SetPedFleeAttributes(driver, 0, 0)
|
||||||
SetPedCombatAttributes(driver, 17, 1)
|
SetPedCombatAttributes(driver, 17, 1)
|
||||||
SetPedSeeingRange(driver, 0.0)
|
SetPedSeeingRange(driver, 0.0)
|
||||||
|
@ -420,6 +757,17 @@ function SpawnTaxiDriver(vehicle)
|
||||||
SetPedAlertness(driver, 0)
|
SetPedAlertness(driver, 0)
|
||||||
SetPedKeepTask(driver, true)
|
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)
|
-- Fahrer-Outfit (nur wenn es ein anpassbarer Ped ist)
|
||||||
if driverHash == GetHashKey("mp_m_freemode_01") then
|
if driverHash == GetHashKey("mp_m_freemode_01") then
|
||||||
print("^2[TAXI DEBUG]^7 Setting driver outfit...")
|
print("^2[TAXI DEBUG]^7 Setting driver outfit...")
|
||||||
|
@ -494,138 +842,23 @@ end
|
||||||
function NavigateToPlayer(driver, taxi, playerCoords)
|
function NavigateToPlayer(driver, taxi, playerCoords)
|
||||||
print("^2[TAXI DEBUG]^7 Navigating taxi to player...")
|
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
|
-- 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)
|
local success, nodePos = GetClosestVehicleNodeWithHeading(playerCoords.x, playerCoords.y, playerCoords.z, 1, 3.0, 0)
|
||||||
|
|
||||||
if success then
|
if success then
|
||||||
print("^2[TAXI DEBUG]^7 Found good vehicle node near player")
|
print("^2[TAXI DEBUG]^7 Found good vehicle node near player")
|
||||||
-- Zum Wegpunkt fahren
|
-- 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
|
else
|
||||||
print("^3[TAXI DEBUG]^7 No good vehicle node found, driving directly to player")
|
print("^3[TAXI DEBUG]^7 No good vehicle node found, driving directly to player")
|
||||||
-- Direkt zum Spieler fahren
|
-- Direkt zum Spieler fahren
|
||||||
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
|
|
||||||
|
|
||||||
-- 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)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function MonitorTaxiArrival(taxi, driver, playerCoords)
|
function MonitorTaxiArrival(taxi, driver, playerCoords)
|
||||||
print("^2[TAXI DEBUG]^7 Monitoring taxi arrival...")
|
print("^2[TAXI DEBUG]^7 Monitoring taxi arrival...")
|
||||||
|
|
||||||
|
@ -691,8 +924,6 @@ function MonitorTaxiArrival(taxi, driver, playerCoords)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Event für Einsteigen ins Taxi
|
-- Event für Einsteigen ins Taxi
|
||||||
RegisterNetEvent('taxi:enterTaxi', function()
|
RegisterNetEvent('taxi:enterTaxi', function()
|
||||||
print("^2[TAXI DEBUG]^7 Player entering taxi")
|
print("^2[TAXI DEBUG]^7 Player entering taxi")
|
||||||
|
@ -870,48 +1101,48 @@ function StartTaxiRide(destination, price)
|
||||||
taxiMeter.currentFare = 0
|
taxiMeter.currentFare = 0
|
||||||
taxiMeter.pricePerKm = Config.PricePerKm
|
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
|
-- 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
|
-- Fahrt überwachen
|
||||||
MonitorTaxiRide(destination, price)
|
MonitorTaxiRide(destination, price)
|
||||||
end
|
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)
|
function MonitorTaxiRide(destination, price)
|
||||||
print("^2[TAXI DEBUG]^7 Monitoring taxi ride...")
|
print("^2[TAXI DEBUG]^7 Monitoring taxi ride...")
|
||||||
|
|
||||||
local lastPos = GetEntityCoords(currentTaxi)
|
local rideTimeout = GetGameTimer() + (10 * 60 * 1000) -- 10 Minuten Timeout
|
||||||
local stuckCounter = 0
|
|
||||||
local maxStuckCount = 10
|
|
||||||
local rideTimeout = GetGameTimer() + (10 * 60 * 1000) -- 5 Minuten Timeout
|
|
||||||
|
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
while DoesEntityExist(currentTaxi) and DoesEntityExist(currentDriver) do
|
while DoesEntityExist(currentTaxi) and DoesEntityExist(currentDriver) do
|
||||||
local taxiCoords = GetEntityCoords(currentTaxi)
|
local taxiCoords = GetEntityCoords(currentTaxi)
|
||||||
local distance = #(vector3(destination.x, destination.y, destination.z) - taxiCoords)
|
local distance = #(vector3(destination.x, destination.y, destination.z) - taxiCoords)
|
||||||
local distanceMoved = #(lastPos - taxiCoords)
|
|
||||||
|
|
||||||
-- Überprüfen ob wir angekommen sind
|
-- Überprüfen ob wir angekommen sind
|
||||||
if distance < 10.0 then
|
if distance < 10.0 then
|
||||||
|
@ -934,6 +1165,24 @@ function MonitorTaxiRide(destination, price)
|
||||||
destinationBlip = nil
|
destinationBlip = nil
|
||||||
end
|
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
|
-- Nach 10 Sekunden Taxi despawnen
|
||||||
SetTimeout(10000, function()
|
SetTimeout(10000, function()
|
||||||
DespawnTaxi()
|
DespawnTaxi()
|
||||||
|
@ -942,70 +1191,53 @@ function MonitorTaxiRide(destination, price)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Überprüfen ob das Taxi stecken geblieben ist
|
-- Überprüfen ob die Fahrt zu lange dauert
|
||||||
if distanceMoved < 1.0 then
|
if GetGameTimer() > rideTimeout then
|
||||||
stuckCounter = stuckCounter + 1
|
print("^1[TAXI DEBUG]^7 Taxi ride timed out!")
|
||||||
|
|
||||||
if stuckCounter >= maxStuckCount then
|
-- Berechne verbleibende Distanz
|
||||||
print("^1[TAXI DEBUG]^7 Taxi stuck during ride, attempting recovery")
|
local taxiCoords = GetEntityCoords(currentTaxi)
|
||||||
RecoverStuckTaxi(currentTaxi, currentDriver, vector3(destination.x, destination.y, destination.z))
|
local remainingDistance = #(vector3(destination.x, destination.y, destination.z) - taxiCoords)
|
||||||
stuckCounter = 0
|
|
||||||
|
lib.notify({
|
||||||
|
title = 'Taxi Service',
|
||||||
|
description = 'Die Fahrt dauert zu lange. Noch ' .. math.ceil(remainingDistance) .. 'm bis zum Ziel!',
|
||||||
|
type = 'warning'
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Teleportiere Taxi näher ans Ziel (75% des Weges)
|
||||||
|
local direction = vector3(
|
||||||
|
destination.x - taxiCoords.x,
|
||||||
|
destination.y - taxiCoords.y,
|
||||||
|
destination.z - taxiCoords.z
|
||||||
|
)
|
||||||
|
local normalizedDir = norm(direction)
|
||||||
|
local teleportDistance = remainingDistance * 0.75
|
||||||
|
|
||||||
|
local newPos = vector3(
|
||||||
|
taxiCoords.x + normalizedDir.x * teleportDistance,
|
||||||
|
taxiCoords.y + normalizedDir.y * teleportDistance,
|
||||||
|
taxiCoords.z
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Finde gültige Z-Koordinate
|
||||||
|
local success, groundZ = GetGroundZFor_3dCoord(newPos.x, newPos.y, newPos.z, true)
|
||||||
|
if success then
|
||||||
|
newPos = vector3(newPos.x, newPos.y, groundZ)
|
||||||
end
|
end
|
||||||
else
|
|
||||||
stuckCounter = math.max(0, stuckCounter - 1)
|
-- Teleportiere Taxi
|
||||||
|
SetEntityCoords(currentTaxi, newPos.x, newPos.y, newPos.z, false, false, false, false)
|
||||||
|
|
||||||
|
-- Neues Timeout setzen (2 Minuten)
|
||||||
|
rideTimeout = GetGameTimer() + (2 * 60 * 1000)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Überprüfen ob die Fahrt zu lange dauert
|
|
||||||
if GetGameTimer() > rideTimeout then
|
|
||||||
print("^1[TAXI DEBUG]^7 Taxi ride timed out!")
|
|
||||||
|
|
||||||
-- Berechne verbleibende Distanz
|
|
||||||
local taxiCoords = GetEntityCoords(currentTaxi)
|
|
||||||
local remainingDistance = #(vector3(destination.x, destination.y, destination.z) - taxiCoords)
|
|
||||||
|
|
||||||
lib.notify({
|
|
||||||
title = 'Taxi Service',
|
|
||||||
description = 'Die Fahrt dauert zu lange. Noch ' .. math.ceil(remainingDistance) .. 'm bis zum Ziel!',
|
|
||||||
type = 'warning'
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Teleportiere Taxi näher ans Ziel (75% des Weges)
|
|
||||||
local direction = vector3(
|
|
||||||
destination.x - taxiCoords.x,
|
|
||||||
destination.y - taxiCoords.y,
|
|
||||||
destination.z - taxiCoords.z
|
|
||||||
)
|
|
||||||
local normalizedDir = norm(direction)
|
|
||||||
local teleportDistance = remainingDistance * 0.75
|
|
||||||
|
|
||||||
local newPos = vector3(
|
|
||||||
taxiCoords.x + normalizedDir.x * teleportDistance,
|
|
||||||
taxiCoords.y + normalizedDir.y * teleportDistance,
|
|
||||||
taxiCoords.z
|
|
||||||
)
|
|
||||||
|
|
||||||
-- Finde gültige Z-Koordinate
|
|
||||||
local success, groundZ = GetGroundZFor_3dCoord(newPos.x, newPos.y, newPos.z, true)
|
|
||||||
if success then
|
|
||||||
newPos = vector3(newPos.x, newPos.y, groundZ)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Teleportiere Taxi
|
|
||||||
SetEntityCoords(currentTaxi, newPos.x, newPos.y, newPos.z, false, false, false, false)
|
|
||||||
|
|
||||||
-- Neues Timeout setzen (2 Minuten)
|
|
||||||
rideTimeout = GetGameTimer() + (2 * 60 * 1000)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
lastPos = taxiCoords
|
|
||||||
Wait(2000)
|
Wait(2000)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function SelfDriveTaxi()
|
function SelfDriveTaxi()
|
||||||
print("^2[TAXI DEBUG]^7 Player driving taxi themselves")
|
print("^2[TAXI DEBUG]^7 Player driving taxi themselves")
|
||||||
|
|
||||||
|
@ -1031,7 +1263,6 @@ function SelfDriveTaxi()
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function ExitTaxi()
|
function ExitTaxi()
|
||||||
print("^2[TAXI DEBUG]^7 Player exiting taxi")
|
print("^2[TAXI DEBUG]^7 Player exiting taxi")
|
||||||
|
|
||||||
|
@ -1054,7 +1285,6 @@ function ExitTaxi()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function DespawnTaxi()
|
function DespawnTaxi()
|
||||||
print("^2[TAXI DEBUG]^7 Despawning taxi")
|
print("^2[TAXI DEBUG]^7 Despawning taxi")
|
||||||
|
|
||||||
|
@ -1144,7 +1374,6 @@ function CalculateDistanceToCoords(coords)
|
||||||
return #(playerCoords - coords)
|
return #(playerCoords - coords)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Command um Taxi zu stoppen
|
-- Command um Taxi zu stoppen
|
||||||
RegisterCommand('stoptaxi', function()
|
RegisterCommand('stoptaxi', function()
|
||||||
if currentTaxi and DoesEntityExist(currentTaxi) then
|
if currentTaxi and DoesEntityExist(currentTaxi) then
|
||||||
|
@ -1242,7 +1471,6 @@ function EndTaxiRide()
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Thread zum Überwachen des Einsteigens ins Taxi (ohne qb-target)
|
-- Thread zum Überwachen des Einsteigens ins Taxi (ohne qb-target)
|
||||||
CreateThread(function()
|
CreateThread(function()
|
||||||
while true do
|
while true do
|
||||||
|
@ -1270,7 +1498,6 @@ CreateThread(function()
|
||||||
if IsControlJustReleased(0, 38) then -- E Taste
|
if IsControlJustReleased(0, 38) then -- E Taste
|
||||||
-- Spieler will einsteigen
|
-- Spieler will einsteigen
|
||||||
lib.hideTextUI()
|
lib.hideTextUI()
|
||||||
|
|
||||||
-- Spieler hinten einsteigen lassen
|
-- Spieler hinten einsteigen lassen
|
||||||
local seatIndex = 1 -- Hinten links
|
local seatIndex = 1 -- Hinten links
|
||||||
if not IsVehicleSeatFree(currentTaxi, 1) then
|
if not IsVehicleSeatFree(currentTaxi, 1) then
|
||||||
|
@ -1317,3 +1544,6 @@ AddEventHandler('onResourceStop', function(resourceName)
|
||||||
print("^2[TAXI DEBUG]^7 Main cleanup completed")
|
print("^2[TAXI DEBUG]^7 Main cleanup completed")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,7 @@ Config.KnownDestinations = {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name = "Paleto Bay",
|
name = "Paleto Bay",
|
||||||
coords = vector3(-276.0, 6635.0, 7.5),
|
coords = vector3(-296.31, 6056.98, 31.36),
|
||||||
price = 100
|
price = 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue