forked from Simnation/Main
ed
This commit is contained in:
parent
b56b025204
commit
fefd1dfd7a
2 changed files with 453 additions and 174 deletions
|
@ -45,8 +45,8 @@ function CallTaxi()
|
|||
|
||||
print("^2[TAXI DEBUG]^7 Player coords: " .. tostring(playerCoords))
|
||||
|
||||
-- Spawn-Position für Taxi finden - Direkt aus Config
|
||||
local spawnCoords = GetTaxiSpawnPosition(playerCoords)
|
||||
-- Verbesserte Spawn-Position für Taxi finden
|
||||
local spawnCoords = GetImprovedTaxiSpawnPosition(playerCoords)
|
||||
if not spawnCoords then
|
||||
print("^1[TAXI DEBUG]^7 No spawn position found")
|
||||
lib.notify({
|
||||
|
@ -57,7 +57,7 @@ function CallTaxi()
|
|||
return
|
||||
end
|
||||
|
||||
print("^2[TAXI DEBUG]^7 Spawn coords found: " .. tostring(spawnCoords))
|
||||
print("^2[TAXI DEBUG]^7 Spawn coords found: " .. tostring(spawnCoords.x) .. ", " .. tostring(spawnCoords.y) .. ", " .. tostring(spawnCoords.z))
|
||||
|
||||
-- Taxi spawnen
|
||||
local taxi = SpawnTaxi(spawnCoords)
|
||||
|
@ -80,55 +80,23 @@ function CallTaxi()
|
|||
currentDriver = driver
|
||||
print("^2[TAXI DEBUG]^7 Driver spawned: " .. driver)
|
||||
|
||||
-- Zum Spieler fahren
|
||||
TaskVehicleDriveToCoord(driver, taxi, playerCoords.x, playerCoords.y, playerCoords.z, 25.0, 0, GetEntityModel(taxi), 786603, 1.0, true)
|
||||
-- Verbesserte Navigation zum Spieler
|
||||
NavigateToPlayer(driver, taxi, playerCoords)
|
||||
|
||||
-- Blip für Taxi erstellen (Entity-Blip)
|
||||
taxiBlip = AddBlipForEntity(taxi)
|
||||
SetBlipSprite(taxiBlip, 198)
|
||||
SetBlipColour(taxiBlip, 5)
|
||||
SetBlipScale(taxiBlip, 0.8)
|
||||
SetBlipDisplay(taxiBlip, 2) -- Zeigt auf Minimap und großer Karte
|
||||
SetBlipShowCone(taxiBlip, true) -- Zeigt Sichtkegel
|
||||
SetBlipAsShortRange(taxiBlip, false) -- Immer sichtbar, egal wie weit entfernt
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString("Dein Taxi")
|
||||
EndTextCommandSetBlipName(taxiBlip)
|
||||
CreateTaxiBlips(taxi)
|
||||
|
||||
-- Zusätzlicher Blip auf der Karte für bessere Sichtbarkeit
|
||||
local taxiCoords = GetEntityCoords(taxi)
|
||||
mapBlip = AddBlipForCoord(taxiCoords.x, taxiCoords.y, taxiCoords.z)
|
||||
SetBlipSprite(mapBlip, 198)
|
||||
SetBlipColour(mapBlip, 5)
|
||||
SetBlipScale(mapBlip, 1.0)
|
||||
SetBlipDisplay(mapBlip, 4) -- Nur auf großer Karte
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString("Dein Taxi")
|
||||
EndTextCommandSetBlipName(mapBlip)
|
||||
-- Überwachung des Taxi-Fortschritts
|
||||
MonitorTaxiProgress(taxi, driver, playerCoords)
|
||||
|
||||
-- Blip aktualisieren während Taxi unterwegs ist
|
||||
CreateThread(function()
|
||||
while DoesEntityExist(taxi) and mapBlip do
|
||||
local taxiCoords = GetEntityCoords(taxi)
|
||||
SetBlipCoords(mapBlip, taxiCoords.x, taxiCoords.y, taxiCoords.z)
|
||||
Wait(1000)
|
||||
end
|
||||
|
||||
-- Blip entfernen wenn Thread beendet
|
||||
if mapBlip then
|
||||
RemoveBlip(mapBlip)
|
||||
mapBlip = nil
|
||||
end
|
||||
end)
|
||||
-- Überwachung der Ankunft
|
||||
MonitorTaxiArrival(taxi, driver, playerCoords)
|
||||
|
||||
lib.notify({
|
||||
title = 'Taxi Service',
|
||||
description = 'Taxi ist unterwegs zu dir! Verfolge es auf der Karte.',
|
||||
type = 'success'
|
||||
})
|
||||
|
||||
-- Überwachung der Ankunft
|
||||
MonitorTaxiArrival(taxi, driver, playerCoords)
|
||||
else
|
||||
print("^1[TAXI DEBUG]^7 Failed to spawn driver")
|
||||
lib.notify({
|
||||
|
@ -140,87 +108,151 @@ function CallTaxi()
|
|||
end)
|
||||
end
|
||||
|
||||
function GetTaxiSpawnPosition(playerCoords)
|
||||
print("^2[TAXI DEBUG]^7 Finding spawn position...")
|
||||
function GetImprovedTaxiSpawnPosition(playerCoords)
|
||||
print("^2[TAXI DEBUG]^7 Finding improved spawn position...")
|
||||
|
||||
-- Prüfen ob Config.MobileTaxiSpawns existiert und nicht leer ist
|
||||
if not Config.MobileTaxiSpawns or #Config.MobileTaxiSpawns == 0 then
|
||||
print("^1[TAXI DEBUG]^7 Config.MobileTaxiSpawns is missing or empty")
|
||||
return nil
|
||||
-- Versuche zuerst einen Straßenknotenpunkt zu finden
|
||||
local roadPosition = nil
|
||||
local foundNode = false
|
||||
local nodePos = vector3(0.0, 0.0, 0.0)
|
||||
|
||||
-- Versuche einen Straßenknotenpunkt in optimaler Entfernung zu finden
|
||||
foundNode, nodePos = GetClosestVehicleNode(playerCoords.x, playerCoords.y, playerCoords.z, 1, 3.0, 0)
|
||||
|
||||
if foundNode then
|
||||
local nodeDistance = #(playerCoords - nodePos)
|
||||
if nodeDistance > 50.0 and nodeDistance < 150.0 then
|
||||
roadPosition = nodePos
|
||||
print("^2[TAXI DEBUG]^7 Found road node for spawn at distance: " .. nodeDistance)
|
||||
return {x = roadPosition.x, y = roadPosition.y, z = roadPosition.z, w = 0.0}
|
||||
end
|
||||
end
|
||||
|
||||
-- Alle Spawn-Positionen nach Entfernung sortieren
|
||||
local sortedSpawns = {}
|
||||
for i, spawnPos in ipairs(Config.MobileTaxiSpawns) do
|
||||
local distance = #(playerCoords - vector3(spawnPos.x, spawnPos.y, spawnPos.z))
|
||||
table.insert(sortedSpawns, {
|
||||
coords = spawnPos,
|
||||
distance = distance
|
||||
})
|
||||
-- Versuche einen weiteren Knotenpunkt mit größerem Radius
|
||||
foundNode, nodePos = GetClosestMajorVehicleNode(playerCoords.x, playerCoords.y, playerCoords.z, 100.0, 0)
|
||||
|
||||
if foundNode then
|
||||
local nodeDistance = #(playerCoords - nodePos)
|
||||
if nodeDistance > 40.0 and nodeDistance < 200.0 then
|
||||
roadPosition = nodePos
|
||||
print("^2[TAXI DEBUG]^7 Found major road node for spawn at distance: " .. nodeDistance)
|
||||
return {x = roadPosition.x, y = roadPosition.y, z = roadPosition.z, w = 0.0}
|
||||
end
|
||||
end
|
||||
|
||||
-- Nach Entfernung sortieren (nächste zuerst)
|
||||
table.sort(sortedSpawns, function(a, b)
|
||||
return a.distance < b.distance
|
||||
end)
|
||||
|
||||
-- Prüfen ob die nächsten Positionen frei sind
|
||||
for i, spawn in ipairs(sortedSpawns) do
|
||||
local spawnCoords = spawn.coords
|
||||
-- Fallback auf Config-Positionen
|
||||
if Config.MobileTaxiSpawns and #Config.MobileTaxiSpawns > 0 then
|
||||
-- Alle Spawn-Positionen nach Entfernung sortieren
|
||||
local sortedSpawns = {}
|
||||
for i, spawnPos in ipairs(Config.MobileTaxiSpawns) do
|
||||
local distance = #(playerCoords - vector3(spawnPos.x, spawnPos.y, spawnPos.z))
|
||||
table.insert(sortedSpawns, {
|
||||
coords = spawnPos,
|
||||
distance = distance
|
||||
})
|
||||
end
|
||||
|
||||
-- Prüfen ob Position frei ist
|
||||
local clearArea = true
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
-- Nach Entfernung sortieren (nächste zuerst)
|
||||
table.sort(sortedSpawns, function(a, b)
|
||||
return a.distance < b.distance
|
||||
end)
|
||||
|
||||
-- Prüfen ob andere Fahrzeuge in der Nähe sind
|
||||
for _, vehicle in ipairs(vehicles) do
|
||||
local vehCoords = GetEntityCoords(vehicle)
|
||||
if #(vector3(spawnCoords.x, spawnCoords.y, spawnCoords.z) - vehCoords) < 5.0 then
|
||||
clearArea = false
|
||||
break
|
||||
-- Prüfen ob die nächsten Positionen frei sind
|
||||
for i, spawn in ipairs(sortedSpawns) do
|
||||
local spawnCoords = spawn.coords
|
||||
|
||||
-- Prüfen ob Position frei ist
|
||||
local clearArea = true
|
||||
local vehicles = GetGamePool('CVehicle')
|
||||
|
||||
-- Prüfen ob andere Fahrzeuge in der Nähe sind
|
||||
for _, vehicle in ipairs(vehicles) do
|
||||
local vehCoords = GetEntityCoords(vehicle)
|
||||
if #(vector3(spawnCoords.x, spawnCoords.y, spawnCoords.z) - vehCoords) < 5.0 then
|
||||
clearArea = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Wenn Position frei ist, verwenden
|
||||
if clearArea then
|
||||
print("^2[TAXI DEBUG]^7 Using spawn position from config: " .. tostring(spawnCoords.x) .. ", " .. tostring(spawnCoords.y) .. ", " .. tostring(spawnCoords.z) .. " (Distance: " .. spawn.distance .. "m)")
|
||||
return spawnCoords
|
||||
end
|
||||
end
|
||||
|
||||
-- Wenn Position frei ist, verwenden
|
||||
if clearArea then
|
||||
print("^2[TAXI DEBUG]^7 Using spawn position from config: " .. tostring(spawnCoords) .. " (Distance: " .. spawn.distance .. "m)")
|
||||
return spawnCoords
|
||||
end
|
||||
-- Wenn keine freie Position gefunden wurde, die am weitesten entfernte verwenden
|
||||
local fallbackSpawn = sortedSpawns[#sortedSpawns].coords
|
||||
print("^3[TAXI DEBUG]^7 No clear spawn position found, using fallback: " .. tostring(fallbackSpawn.x) .. ", " .. tostring(fallbackSpawn.y) .. ", " .. tostring(fallbackSpawn.z))
|
||||
return fallbackSpawn
|
||||
end
|
||||
|
||||
-- Wenn keine freie Position gefunden wurde, die am weitesten entfernte verwenden
|
||||
local fallbackSpawn = sortedSpawns[#sortedSpawns].coords
|
||||
print("^3[TAXI DEBUG]^7 No clear spawn position found, using fallback: " .. tostring(fallbackSpawn))
|
||||
return fallbackSpawn
|
||||
-- Absolute Notfall-Fallback: Zufällige Position um Spieler herum
|
||||
local angle = math.random() * 2 * math.pi
|
||||
local distance = math.random(80, 120)
|
||||
local x = playerCoords.x + math.cos(angle) * distance
|
||||
local y = playerCoords.y + math.sin(angle) * distance
|
||||
local z = playerCoords.z
|
||||
|
||||
-- Versuche eine gültige Z-Koordinate zu bekommen
|
||||
local success, groundZ = GetGroundZFor_3dCoord(x, y, z, true)
|
||||
if success then
|
||||
z = groundZ
|
||||
end
|
||||
|
||||
print("^3[TAXI DEBUG]^7 Using emergency random spawn position")
|
||||
return {x = x, y = y, z = z, w = 0.0}
|
||||
end
|
||||
|
||||
function SpawnTaxi(coords)
|
||||
print("^2[TAXI DEBUG]^7 Spawning taxi at: " .. tostring(coords))
|
||||
print("^2[TAXI DEBUG]^7 Spawning taxi at: " .. tostring(coords.x) .. ", " .. tostring(coords.y) .. ", " .. tostring(coords.z))
|
||||
|
||||
-- Sicherstellen dass wir ein gültiges Taxi-Model haben
|
||||
local taxiModel = nil
|
||||
if Config.TaxiVehicles and #Config.TaxiVehicles > 0 then
|
||||
taxiModel = GetHashKey(Config.TaxiVehicles[1].model)
|
||||
-- Zufälliges Taxi-Model aus Config wählen
|
||||
local randomIndex = math.random(1, #Config.TaxiVehicles)
|
||||
taxiModel = GetHashKey(Config.TaxiVehicles[randomIndex].model)
|
||||
else
|
||||
taxiModel = GetHashKey("taxi") -- Fallback
|
||||
end
|
||||
|
||||
print("^2[TAXI DEBUG]^7 Taxi model hash: " .. taxiModel)
|
||||
|
||||
-- Model laden mit Timeout
|
||||
RequestModel(taxiModel)
|
||||
local modelLoaded = false
|
||||
local timeout = GetGameTimer() + 10000
|
||||
while not HasModelLoaded(taxiModel) and GetGameTimer() < timeout do
|
||||
print("^3[TAXI DEBUG]^7 Waiting for taxi model to load...")
|
||||
Wait(100)
|
||||
|
||||
while not modelLoaded and GetGameTimer() < timeout do
|
||||
modelLoaded = HasModelLoaded(taxiModel)
|
||||
if not modelLoaded then
|
||||
print("^3[TAXI DEBUG]^7 Waiting for taxi model to load...")
|
||||
Wait(100)
|
||||
end
|
||||
end
|
||||
|
||||
if not HasModelLoaded(taxiModel) then
|
||||
print("^1[TAXI DEBUG]^7 Failed to load taxi model!")
|
||||
return nil
|
||||
if not modelLoaded then
|
||||
print("^1[TAXI DEBUG]^7 Failed to load taxi model! Trying default model.")
|
||||
SetModelAsNoLongerNeeded(taxiModel)
|
||||
|
||||
-- Versuche Standard-Taxi als Fallback
|
||||
taxiModel = GetHashKey("taxi")
|
||||
RequestModel(taxiModel)
|
||||
|
||||
timeout = GetGameTimer() + 5000
|
||||
while not HasModelLoaded(taxiModel) and GetGameTimer() < timeout do
|
||||
Wait(100)
|
||||
end
|
||||
|
||||
if not HasModelLoaded(taxiModel) then
|
||||
print("^1[TAXI DEBUG]^7 Failed to load default taxi model!")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
-- Direkt die Koordinaten aus der Config verwenden
|
||||
local taxi = CreateVehicle(taxiModel, coords.x, coords.y, coords.z, coords.w, true, false)
|
||||
-- Fahrzeug erstellen
|
||||
local taxi = CreateVehicle(taxiModel, coords.x, coords.y, coords.z, coords.w or 0.0, true, false)
|
||||
|
||||
if not DoesEntityExist(taxi) then
|
||||
print("^1[TAXI DEBUG]^7 Failed to create taxi vehicle!")
|
||||
|
@ -229,6 +261,7 @@ function SpawnTaxi(coords)
|
|||
|
||||
print("^2[TAXI DEBUG]^7 Taxi created successfully: " .. taxi)
|
||||
|
||||
-- Fahrzeug konfigurieren
|
||||
SetEntityAsMissionEntity(taxi, true, true)
|
||||
SetVehicleOnGroundProperly(taxi)
|
||||
SetVehicleEngineOn(taxi, true, true, false)
|
||||
|
@ -241,32 +274,40 @@ function SpawnTaxi(coords)
|
|||
print("^2[TAXI DEBUG]^7 Taxi livery set")
|
||||
end
|
||||
|
||||
-- Fahrzeug-Extras aktivieren falls vorhanden
|
||||
for i = 1, 14 do
|
||||
if DoesExtraExist(taxi, i) then
|
||||
SetVehicleExtra(taxi, i, false) -- Extra aktivieren
|
||||
end
|
||||
end
|
||||
|
||||
-- Fahrzeug-Farbe setzen (Gelb für Taxis)
|
||||
SetVehicleColours(taxi, 88, 88) -- Taxi Yellow
|
||||
|
||||
SetModelAsNoLongerNeeded(taxiModel)
|
||||
return taxi
|
||||
end
|
||||
|
||||
|
||||
|
||||
function SpawnTaxiDriver(vehicle)
|
||||
print("^2[TAXI DEBUG]^7 Spawning taxi driver...")
|
||||
|
||||
-- Bessere Fahrer-Models mit Fallbacks
|
||||
local driverModels = {
|
||||
"A_C_Chimp", -- Standard Male (sollte immer verfügbar sein)
|
||||
"U_M_M_Jesus_01", -- Standard Female
|
||||
"a_m_y_business_01", -- Business Male
|
||||
"a_f_y_business_01", -- Business Female
|
||||
"a_m_m_business_01", -- Business Male 2
|
||||
"a_m_y_downtown_01", -- Downtown Male
|
||||
"A_M_M_SouCent_02", -- Pilot
|
||||
"IG_Tonya" -- Dealer
|
||||
"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
|
||||
"a_m_y_downtown_01", -- Downtown Male
|
||||
"a_m_m_farmer_01", -- Farmer
|
||||
"a_m_y_hipster_01", -- Hipster
|
||||
"a_m_y_beach_01" -- Beach Guy
|
||||
}
|
||||
|
||||
local driver = nil
|
||||
local driverHash = nil
|
||||
|
||||
-- Versuche verschiedene Models
|
||||
for i, modelName in pairs(driverModels) do
|
||||
for i, modelName in ipairs(driverModels) do
|
||||
print("^2[TAXI DEBUG]^7 Trying driver model " .. i .. ": " .. modelName)
|
||||
driverHash = GetHashKey(modelName)
|
||||
|
||||
|
@ -303,37 +344,6 @@ function SpawnTaxiDriver(vehicle)
|
|||
end
|
||||
|
||||
-- Wenn immer noch kein Fahrer erstellt wurde
|
||||
if not driver or not DoesEntityExist(driver) then
|
||||
print("^1[TAXI DEBUG]^7 All driver models failed, trying emergency fallback...")
|
||||
|
||||
-- Notfall-Fallback: Versuche den einfachsten Ped zu erstellen
|
||||
local emergencyModels = {
|
||||
`mp_m_freemode_01`,
|
||||
`a_m_y_hipster_01`,
|
||||
`a_m_m_farmer_01`,
|
||||
`a_m_y_beach_01`
|
||||
}
|
||||
|
||||
for _, hash in pairs(emergencyModels) do
|
||||
RequestModel(hash)
|
||||
local timeout = GetGameTimer() + 5000
|
||||
while not HasModelLoaded(hash) and GetGameTimer() < timeout do
|
||||
Wait(50)
|
||||
end
|
||||
|
||||
if HasModelLoaded(hash) then
|
||||
driver = CreatePedInsideVehicle(vehicle, 26, hash, -1, true, false)
|
||||
if DoesEntityExist(driver) then
|
||||
print("^2[TAXI DEBUG]^7 Emergency driver created with hash: " .. hash)
|
||||
driverHash = hash
|
||||
break
|
||||
end
|
||||
SetModelAsNoLongerNeeded(hash)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Wenn immer noch kein Fahrer
|
||||
if not driver or not DoesEntityExist(driver) then
|
||||
print("^1[TAXI DEBUG]^7 Could not create any driver! Continuing without driver...")
|
||||
return nil
|
||||
|
@ -343,29 +353,33 @@ function SpawnTaxiDriver(vehicle)
|
|||
print("^2[TAXI DEBUG]^7 Configuring driver...")
|
||||
|
||||
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)
|
||||
SetPedHearingRange(driver, 0.0)
|
||||
SetPedAlertness(driver, 0)
|
||||
SetPedKeepTask(driver, true)
|
||||
SetBlockingOfNonTemporaryEvents(driver, true)
|
||||
|
||||
-- Fahrer-Outfit (nur wenn es ein anpassbarer Ped ist)
|
||||
if driverHash == GetHashKey("mp_m_freemode_01") or driverHash == GetHashKey("mp_f_freemode_01") then
|
||||
if driverHash == GetHashKey("mp_m_freemode_01") then
|
||||
print("^2[TAXI DEBUG]^7 Setting driver outfit...")
|
||||
|
||||
-- Basis-Outfit für Taxi-Fahrer
|
||||
SetPedComponentVariation(driver, 8, 15, 0, 0) -- Undershirt
|
||||
SetPedComponentVariation(driver, 11, 28, 0, 0) -- Jacket
|
||||
SetPedComponentVariation(driver, 4, 10, 0, 0) -- Pants
|
||||
SetPedComponentVariation(driver, 6, 10, 0, 0) -- Shoes
|
||||
SetPedComponentVariation(driver, 1, 0, 0, 0) -- Mask
|
||||
SetPedComponentVariation(driver, 3, 0, 0, 0) -- Arms
|
||||
SetPedComponentVariation(driver, 5, 0, 0, 0) -- Bag
|
||||
SetPedComponentVariation(driver, 7, 0, 0, 0) -- Tie
|
||||
SetPedComponentVariation(driver, 9, 0, 0, 0) -- Body Armor
|
||||
SetPedComponentVariation(driver, 10, 0, 0, 0) -- Decals
|
||||
SetPedComponentVariation(driver, 0, 0, 0, 0) -- Face
|
||||
SetPedComponentVariation(driver, 2, 1, 0, 0) -- Hair
|
||||
SetPedComponentVariation(driver, 8, 15, 0, 0) -- Undershirt
|
||||
SetPedComponentVariation(driver, 11, 91, 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)
|
||||
|
@ -380,14 +394,178 @@ function SpawnTaxiDriver(vehicle)
|
|||
return driver
|
||||
end
|
||||
|
||||
function CreateTaxiBlips(taxi)
|
||||
-- Blip für Taxi erstellen (Entity-Blip)
|
||||
taxiBlip = AddBlipForEntity(taxi)
|
||||
SetBlipSprite(taxiBlip, 198)
|
||||
SetBlipColour(taxiBlip, 5)
|
||||
SetBlipScale(taxiBlip, 0.8)
|
||||
SetBlipDisplay(taxiBlip, 2) -- Zeigt auf Minimap und großer Karte
|
||||
SetBlipShowCone(taxiBlip, true) -- Zeigt Sichtkegel
|
||||
SetBlipAsShortRange(taxiBlip, false) -- Immer sichtbar, egal wie weit entfernt
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString("Dein Taxi")
|
||||
EndTextCommandSetBlipName(taxiBlip)
|
||||
|
||||
-- Zusätzlicher Blip auf der Karte für bessere Sichtbarkeit
|
||||
local taxiCoords = GetEntityCoords(taxi)
|
||||
mapBlip = AddBlipForCoord(taxiCoords.x, taxiCoords.y, taxiCoords.z)
|
||||
SetBlipSprite(mapBlip, 198)
|
||||
SetBlipColour(mapBlip, 5)
|
||||
SetBlipScale(mapBlip, 1.0)
|
||||
SetBlipDisplay(mapBlip, 4) -- Nur auf großer Karte
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString("Dein Taxi")
|
||||
EndTextCommandSetBlipName(mapBlip)
|
||||
|
||||
-- Blip aktualisieren während Taxi unterwegs ist
|
||||
CreateThread(function()
|
||||
while DoesEntityExist(taxi) and mapBlip do
|
||||
local taxiCoords = GetEntityCoords(taxi)
|
||||
SetBlipCoords(mapBlip, taxiCoords.x, taxiCoords.y, taxiCoords.z)
|
||||
Wait(1000)
|
||||
end
|
||||
|
||||
-- Blip entfernen wenn Thread beendet
|
||||
if mapBlip then
|
||||
RemoveBlip(mapBlip)
|
||||
mapBlip = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
function NavigateToPlayer(driver, taxi, playerCoords)
|
||||
print("^2[TAXI DEBUG]^7 Navigating taxi to player...")
|
||||
|
||||
-- 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)
|
||||
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)
|
||||
}
|
||||
|
||||
function MonitorTaxiProgress(taxi, driver, playerCoords)
|
||||
print("^2[TAXI DEBUG]^7 Monitoring taxi progress...")
|
||||
|
||||
local lastPos = GetEntityCoords(taxi)
|
||||
local stuckCounter = 0
|
||||
local maxStuckCount = 5
|
||||
local totalStuckEvents = 0
|
||||
local maxTotalStuckEvents = 3
|
||||
|
||||
CreateThread(function()
|
||||
while DoesEntityExist(taxi) and DoesEntityExist(driver) do
|
||||
Wait(3000)
|
||||
|
||||
-- Check if taxi exists and is moving
|
||||
if not DoesEntityExist(taxi) or not DoesEntityExist(driver) then
|
||||
print("^1[TAXI DEBUG]^7 Taxi or driver no longer exists")
|
||||
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
|
||||
}
|
||||
|
||||
function MonitorTaxiArrival(taxi, driver, playerCoords)
|
||||
print("^2[TAXI DEBUG]^7 Monitoring taxi arrival...")
|
||||
|
||||
local arrivalTimeout = GetGameTimer() + (120 * 1000) -- 2 minute timeout
|
||||
|
||||
CreateThread(function()
|
||||
while DoesEntityExist(taxi) and (not driver or DoesEntityExist(driver)) do
|
||||
local taxiCoords = GetEntityCoords(taxi)
|
||||
local distance = #(playerCoords - taxiCoords)
|
||||
local currentPlayerCoords = GetEntityCoords(PlayerPedId())
|
||||
local distance = #(currentPlayerCoords - taxiCoords)
|
||||
|
||||
-- Check if taxi is close to player
|
||||
if distance < 15.0 then
|
||||
print("^2[TAXI DEBUG]^7 Taxi arrived!")
|
||||
|
||||
|
@ -420,10 +598,26 @@ function MonitorTaxiArrival(taxi, driver, playerCoords)
|
|||
break
|
||||
end
|
||||
|
||||
-- Check for timeout
|
||||
if GetGameTimer() > arrivalTimeout then
|
||||
print("^1[TAXI DEBUG]^7 Taxi arrival timed out!")
|
||||
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()
|
||||
break
|
||||
end
|
||||
|
||||
Wait(2000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
-- Event für Einsteigen ins Taxi
|
||||
RegisterNetEvent('taxi:enterTaxi', function()
|
||||
|
@ -484,7 +678,6 @@ RegisterNetEvent('taxi:enterTaxi', function()
|
|||
end)
|
||||
end)
|
||||
|
||||
|
||||
function OpenDestinationMenu()
|
||||
print("^2[TAXI DEBUG]^7 Opening destination menu")
|
||||
|
||||
|
@ -560,7 +753,7 @@ function OpenDestinationMenu()
|
|||
end
|
||||
|
||||
function StartTaxiRide(destination, price)
|
||||
print("^2[TAXI DEBUG]^7 Starting taxi ride to: " .. tostring(destination))
|
||||
print("^2[TAXI DEBUG]^7 Starting taxi ride to: " .. tostring(destination.x) .. ", " .. tostring(destination.y) .. ", " .. tostring(destination.z))
|
||||
|
||||
if not currentTaxi or not DoesEntityExist(currentTaxi) then
|
||||
print("^1[TAXI DEBUG]^7 No taxi exists for ride")
|
||||
|
@ -584,29 +777,68 @@ function StartTaxiRide(destination, price)
|
|||
})
|
||||
|
||||
-- Destination Blip erstellen
|
||||
if destinationBlip then
|
||||
RemoveBlip(destinationBlip)
|
||||
end
|
||||
|
||||
destinationBlip = AddBlipForCoord(destination.x, destination.y, destination.z)
|
||||
SetBlipSprite(destinationBlip, 1)
|
||||
SetBlipColour(destinationBlip, 2)
|
||||
SetBlipScale(destinationBlip, 0.8)
|
||||
SetBlipRoute(destinationBlip, true)
|
||||
BeginTextCommandSetBlipName("STRING")
|
||||
AddTextComponentString("Taxi Ziel")
|
||||
EndTextCommandSetBlipName(destinationBlip)
|
||||
|
||||
-- Zum Ziel fahren
|
||||
TaskVehicleDriveToCoord(currentDriver, currentTaxi, destination.x, destination.y, destination.z, 25.0, 0, GetEntityModel(currentTaxi), 786603, 1.0, true)
|
||||
-- Taximeter starten
|
||||
taxiMeter.isRunning = true
|
||||
taxiMeter.startCoords = GetEntityCoords(currentTaxi)
|
||||
taxiMeter.currentFare = 0
|
||||
taxiMeter.pricePerKm = Config.PricePerKm
|
||||
|
||||
-- Zum Ziel fahren mit verbesserter Navigation
|
||||
NavigateToDestination(currentDriver, currentTaxi, destination)
|
||||
|
||||
-- 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)
|
||||
}
|
||||
|
||||
function MonitorTaxiRide(destination, price)
|
||||
print("^2[TAXI DEBUG]^7 Monitoring taxi ride...")
|
||||
|
||||
local lastPos = GetEntityCoords(currentTaxi)
|
||||
local stuckCounter = 0
|
||||
local maxStuckCount = 5
|
||||
local rideTimeout = GetGameTimer() + (5 * 60 * 1000) -- 5 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
|
||||
-- Angekommen
|
||||
TaskVehicleTempAction(currentDriver, currentTaxi, 27, 3000)
|
||||
|
@ -635,10 +867,54 @@ 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
|
||||
print("^1[TAXI 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(currentTaxi, nearDestination.x, nearDestination.y, nearDestination.z, false, false, false, false)
|
||||
|
||||
-- Neues Timeout setzen (1 Minute)
|
||||
rideTimeout = GetGameTimer() + (60 * 1000)
|
||||
}
|
||||
|
||||
lastPos = taxiCoords
|
||||
Wait(2000)
|
||||
end
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
function SelfDriveTaxi()
|
||||
print("^2[TAXI DEBUG]^7 Player driving taxi themselves")
|
||||
|
@ -663,7 +939,7 @@ function SelfDriveTaxi()
|
|||
description = 'Du fährst das Taxi jetzt selbst. Nutze /stoptaxi um es zu beenden.',
|
||||
type = 'info'
|
||||
})
|
||||
end
|
||||
}
|
||||
|
||||
function ExitTaxi()
|
||||
print("^2[TAXI DEBUG]^7 Player exiting taxi")
|
||||
|
@ -685,7 +961,7 @@ function ExitTaxi()
|
|||
SetTimeout(5000, function()
|
||||
DespawnTaxi()
|
||||
end)
|
||||
end
|
||||
}
|
||||
|
||||
function DespawnTaxi()
|
||||
print("^2[TAXI DEBUG]^7 Despawning taxi")
|
||||
|
@ -706,7 +982,7 @@ function DespawnTaxi()
|
|||
local driveToY = taxiCoords.y + math.sin(angle) * distance
|
||||
|
||||
-- Taxi wegfahren lassen
|
||||
TaskVehicleDriveToCoord(currentDriver, currentTaxi, driveToX, driveToY, taxiCoords.z, 25.0, 0, GetEntityModel(currentTaxi), 786603, 1.0, true)
|
||||
TaskVehicleDriveToCoordLongrange(currentDriver, currentTaxi, driveToX, driveToY, taxiCoords.z, 25.0, 786603, 5.0)
|
||||
|
||||
-- Blips entfernen
|
||||
if taxiBlip then
|
||||
|
@ -769,12 +1045,12 @@ function DespawnTaxi()
|
|||
|
||||
print("^2[TAXI DEBUG]^7 Taxi despawn completed (no driver)")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
||||
function CalculateDistanceToCoords(coords)
|
||||
local playerCoords = GetEntityCoords(PlayerPedId())
|
||||
return #(playerCoords - coords)
|
||||
end
|
||||
}
|
||||
|
||||
-- Command um Taxi zu stoppen
|
||||
RegisterCommand('stoptaxi', function()
|
||||
|
@ -794,7 +1070,6 @@ RegisterCommand('stoptaxi', function()
|
|||
end
|
||||
end)
|
||||
|
||||
|
||||
-- Thread zum Überwachen der Tasten im Taxi
|
||||
CreateThread(function()
|
||||
while true do
|
||||
|
@ -872,9 +1147,7 @@ function EndTaxiRide()
|
|||
DespawnTaxi()
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
|
||||
}
|
||||
|
||||
-- Thread zum Überwachen des Einsteigens ins Taxi (ohne qb-target)
|
||||
CreateThread(function()
|
||||
|
@ -899,6 +1172,7 @@ CreateThread(function()
|
|||
}
|
||||
})
|
||||
|
||||
-- Prüfen ob E gedrückt wird
|
||||
if IsControlJustReleased(0, 38) then -- E Taste
|
||||
-- Spieler will einsteigen
|
||||
lib.hideTextUI()
|
||||
|
@ -916,15 +1190,17 @@ CreateThread(function()
|
|||
|
||||
-- Warten bis eingestiegen
|
||||
local entryTimeout = GetGameTimer() + 10000
|
||||
while GetGameTimer() < entryTimeout do
|
||||
if IsPedInVehicle(playerPed, currentTaxi, false) then
|
||||
-- Spieler ist eingestiegen
|
||||
Wait(1000)
|
||||
OpenDestinationMenu()
|
||||
break
|
||||
CreateThread(function()
|
||||
while GetGameTimer() < entryTimeout do
|
||||
if IsPedInVehicle(playerPed, currentTaxi, false) then
|
||||
-- Spieler ist eingestiegen
|
||||
Wait(1000)
|
||||
OpenDestinationMenu()
|
||||
break
|
||||
end
|
||||
Wait(100)
|
||||
end
|
||||
Wait(100)
|
||||
end
|
||||
end)
|
||||
end
|
||||
else
|
||||
lib.hideTextUI()
|
||||
|
@ -933,14 +1209,17 @@ CreateThread(function()
|
|||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
-- Cleanup beim Resource Stop
|
||||
AddEventHandler('onResourceStop', function(resourceName)
|
||||
if GetCurrentResourceName() == resourceName then
|
||||
print("^2[TAXI DEBUG]^7 Cleaning up main script...")
|
||||
|
||||
-- UI ausblenden
|
||||
lib.hideTextUI()
|
||||
|
||||
-- Taxi despawnen
|
||||
DespawnTaxi()
|
||||
|
||||
print("^2[TAXI DEBUG]^7 Main cleanup completed")
|
||||
end
|
||||
end)
|
||||
|
||||
|
|
|
@ -123,7 +123,7 @@ Config.KnownDestinations = {
|
|||
},
|
||||
{
|
||||
name = "Sandy Shores",
|
||||
coords = vector3(1836.0, 3672.0, 34.0),
|
||||
coords = vector3(1815.27, 3649.01, 34.25),
|
||||
price = 75
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue