forked from Simnation/Main
443 lines
14 KiB
Lua
443 lines
14 KiB
Lua
local QBCore = exports['qb-core']:GetCoreObject()
|
|
local currentTaxi = nil
|
|
local taxiDriver = nil
|
|
local inTaxi = false
|
|
local taxiBlip = nil
|
|
local destinationBlip = nil
|
|
local meterRunning = false
|
|
local currentFare = 0
|
|
local lastTaxiCall = 0
|
|
|
|
print("^2[TAXI DEBUG]^7 Client script loaded")
|
|
|
|
-- Taxi rufen Command (Mobile Taxi)
|
|
RegisterCommand('taxi', function()
|
|
print("^2[TAXI DEBUG]^7 /taxi command executed")
|
|
|
|
local currentTime = GetGameTimer()
|
|
if currentTime - lastTaxiCall < (Config.TaxiCallCooldown * 1000) then
|
|
local remainingTime = math.ceil((Config.TaxiCallCooldown * 1000 - (currentTime - lastTaxiCall)) / 1000)
|
|
print("^1[TAXI DEBUG]^7 Cooldown active: " .. remainingTime .. " seconds")
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Du musst noch ' .. remainingTime .. ' Sekunden warten',
|
|
type = 'error'
|
|
})
|
|
return
|
|
end
|
|
|
|
if currentTaxi then
|
|
print("^1[TAXI DEBUG]^7 Taxi already exists")
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Du hast bereits ein Taxi gerufen',
|
|
type = 'error'
|
|
})
|
|
return
|
|
end
|
|
|
|
print("^2[TAXI DEBUG]^7 Calling mobile taxi...")
|
|
CallMobileTaxi()
|
|
end)
|
|
|
|
function CallMobileTaxi()
|
|
print("^2[TAXI DEBUG]^7 CallMobileTaxi function started")
|
|
lastTaxiCall = GetGameTimer()
|
|
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Ein Taxi wurde gerufen und ist auf dem Weg zu dir',
|
|
type = 'success'
|
|
})
|
|
|
|
CreateThread(function()
|
|
print("^2[TAXI DEBUG]^7 Taxi spawn thread started")
|
|
|
|
local playerPed = PlayerPedId()
|
|
local playerCoords = GetEntityCoords(playerPed)
|
|
print("^2[TAXI DEBUG]^7 Player coords: " .. tostring(playerCoords))
|
|
|
|
-- Prüfe ob Config existiert
|
|
if not Config.MobileTaxiSpawns then
|
|
print("^1[TAXI DEBUG]^7 Config.MobileTaxiSpawns not found!")
|
|
return
|
|
end
|
|
|
|
-- Zufällige Spawn-Location wählen
|
|
local spawnLocation = Config.MobileTaxiSpawns[math.random(#Config.MobileTaxiSpawns)]
|
|
print("^2[TAXI DEBUG]^7 Spawn location: " .. tostring(spawnLocation))
|
|
|
|
-- Zufälliges Taxi-Fahrzeug wählen
|
|
local selectedVehicle = SelectRandomTaxi()
|
|
print("^2[TAXI DEBUG]^7 Selected vehicle: " .. selectedVehicle.model)
|
|
|
|
-- Fahrzeug spawnen
|
|
local vehicleHash = GetHashKey(selectedVehicle.model)
|
|
print("^2[TAXI DEBUG]^7 Vehicle hash: " .. vehicleHash)
|
|
|
|
RequestModel(vehicleHash)
|
|
local timeout = GetGameTimer() + 10000
|
|
while not HasModelLoaded(vehicleHash) and GetGameTimer() < timeout do
|
|
print("^3[TAXI DEBUG]^7 Waiting for model to load...")
|
|
Wait(100)
|
|
end
|
|
|
|
if not HasModelLoaded(vehicleHash) then
|
|
print("^1[TAXI DEBUG]^7 Failed to load vehicle model!")
|
|
return
|
|
end
|
|
|
|
print("^2[TAXI DEBUG]^7 Creating vehicle...")
|
|
currentTaxi = CreateVehicle(vehicleHash, spawnLocation.x, spawnLocation.y, spawnLocation.z, spawnLocation.w, true, false)
|
|
|
|
if not DoesEntityExist(currentTaxi) then
|
|
print("^1[TAXI DEBUG]^7 Failed to create vehicle!")
|
|
return
|
|
end
|
|
|
|
print("^2[TAXI DEBUG]^7 Vehicle created successfully: " .. currentTaxi)
|
|
SetEntityAsMissionEntity(currentTaxi, true, true)
|
|
SetVehicleOnGroundProperly(currentTaxi)
|
|
|
|
-- Fahrer spawnen
|
|
local driverHash = GetHashKey("a_m_m_taxi_01")
|
|
RequestModel(driverHash)
|
|
timeout = GetGameTimer() + 10000
|
|
while not HasModelLoaded(driverHash) and GetGameTimer() < timeout do
|
|
print("^3[TAXI DEBUG]^7 Waiting for driver model to load...")
|
|
Wait(100)
|
|
end
|
|
|
|
if not HasModelLoaded(driverHash) then
|
|
print("^1[TAXI DEBUG]^7 Failed to load driver model!")
|
|
DeleteEntity(currentTaxi)
|
|
currentTaxi = nil
|
|
return
|
|
end
|
|
|
|
print("^2[TAXI DEBUG]^7 Creating driver...")
|
|
taxiDriver = CreatePedInsideVehicle(currentTaxi, 26, driverHash, -1, true, false)
|
|
|
|
if not DoesEntityExist(taxiDriver) then
|
|
print("^1[TAXI DEBUG]^7 Failed to create driver!")
|
|
DeleteEntity(currentTaxi)
|
|
currentTaxi = nil
|
|
return
|
|
end
|
|
|
|
print("^2[TAXI DEBUG]^7 Driver created successfully: " .. taxiDriver)
|
|
SetEntityAsMissionEntity(taxiDriver, true, true)
|
|
SetPedFleeAttributes(taxiDriver, 0, 0)
|
|
SetPedCombatAttributes(taxiDriver, 17, 1)
|
|
SetPedSeeingRange(taxiDriver, 0.0)
|
|
SetPedHearingRange(taxiDriver, 0.0)
|
|
SetPedAlertness(taxiDriver, 0)
|
|
SetPedKeepTask(taxiDriver, true)
|
|
|
|
-- Blip erstellen
|
|
taxiBlip = AddBlipForEntity(currentTaxi)
|
|
SetBlipSprite(taxiBlip, 198)
|
|
SetBlipColour(taxiBlip, 5)
|
|
SetBlipScale(taxiBlip, 0.8)
|
|
BeginTextCommandSetBlipName("STRING")
|
|
AddTextComponentString("Taxi")
|
|
EndTextCommandSetBlipName(taxiBlip)
|
|
print("^2[TAXI DEBUG]^7 Blip created")
|
|
|
|
-- Zum Spieler fahren
|
|
print("^2[TAXI DEBUG]^7 Sending taxi to player...")
|
|
TaskVehicleDriveToCoord(taxiDriver, currentTaxi, playerCoords.x, playerCoords.y, playerCoords.z, 20.0, 0, vehicleHash, 786603, 1.0, true)
|
|
|
|
-- Warten bis Taxi ankommt
|
|
local arrived = false
|
|
timeout = GetGameTimer() + (Config.MaxWaitTime * 1000)
|
|
|
|
while not arrived and GetGameTimer() < timeout do
|
|
if not DoesEntityExist(currentTaxi) or not DoesEntityExist(taxiDriver) then
|
|
print("^1[TAXI DEBUG]^7 Taxi or driver disappeared!")
|
|
break
|
|
end
|
|
|
|
local taxiCoords = GetEntityCoords(currentTaxi)
|
|
local distance = #(playerCoords - taxiCoords)
|
|
|
|
if distance < 10.0 then
|
|
arrived = true
|
|
TaskVehicleTempAction(taxiDriver, currentTaxi, 27, 3000)
|
|
|
|
print("^2[TAXI DEBUG]^7 Taxi arrived!")
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Dein Taxi ist angekommen! Steige ein.',
|
|
type = 'success'
|
|
})
|
|
|
|
WaitForPlayerToEnter(selectedVehicle.pricePerKm)
|
|
end
|
|
Wait(1000)
|
|
end
|
|
|
|
if not arrived then
|
|
print("^1[TAXI DEBUG]^7 Taxi failed to arrive in time")
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Das Taxi konnte dich nicht erreichen',
|
|
type = 'error'
|
|
})
|
|
CleanupMobileTaxi()
|
|
end
|
|
end)
|
|
end
|
|
|
|
function SelectRandomTaxi()
|
|
if not Config.TaxiVehicles or #Config.TaxiVehicles == 0 then
|
|
print("^1[TAXI DEBUG]^7 No taxi vehicles configured!")
|
|
return {model = 'taxi', pricePerKm = 5}
|
|
end
|
|
|
|
local totalChance = 0
|
|
for _, vehicle in pairs(Config.TaxiVehicles) do
|
|
totalChance = totalChance + vehicle.spawnChance
|
|
end
|
|
|
|
local randomValue = math.random(1, totalChance)
|
|
local currentChance = 0
|
|
|
|
for _, vehicle in pairs(Config.TaxiVehicles) do
|
|
currentChance = currentChance + vehicle.spawnChance
|
|
if randomValue <= currentChance then
|
|
return vehicle
|
|
end
|
|
end
|
|
|
|
return Config.TaxiVehicles[1]
|
|
end
|
|
|
|
function WaitForPlayerToEnter(pricePerKm)
|
|
print("^2[TAXI DEBUG]^7 Waiting for player to enter...")
|
|
CreateThread(function()
|
|
local timeout = GetGameTimer() + 60000
|
|
|
|
while currentTaxi and GetGameTimer() < timeout do
|
|
local playerPed = PlayerPedId()
|
|
|
|
if IsPedInVehicle(playerPed, currentTaxi, false) then
|
|
inTaxi = true
|
|
print("^2[TAXI DEBUG]^7 Player entered taxi")
|
|
OpenMobileTaxiMenu(pricePerKm)
|
|
break
|
|
end
|
|
|
|
Wait(1000)
|
|
end
|
|
|
|
if not inTaxi then
|
|
print("^1[TAXI DEBUG]^7 Player didn't enter taxi in time")
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Das Taxi ist weggefahren',
|
|
type = 'error'
|
|
})
|
|
CleanupMobileTaxi()
|
|
end
|
|
end)
|
|
end
|
|
|
|
function OpenMobileTaxiMenu(pricePerKm)
|
|
print("^2[TAXI DEBUG]^7 Opening mobile taxi menu")
|
|
local options = {}
|
|
|
|
-- Bekannte Ziele hinzufügen
|
|
for _, destination in pairs(Config.KnownDestinations) do
|
|
local customPrice = math.max(Config.MinFare, math.ceil((CalculateDistance(destination.coords) / 1000) * pricePerKm))
|
|
table.insert(options, {
|
|
title = destination.name,
|
|
description = 'Preis: $' .. customPrice,
|
|
icon = 'map-marker',
|
|
onSelect = function()
|
|
StartMobileTaxiRide(destination.coords, customPrice)
|
|
end
|
|
})
|
|
end
|
|
|
|
-- Waypoint Option
|
|
table.insert(options, {
|
|
title = 'Zu meinem Waypoint',
|
|
description = 'Fahre zu deinem gesetzten Waypoint',
|
|
icon = 'location-dot',
|
|
onSelect = function()
|
|
local waypoint = GetFirstBlipInfoId(8)
|
|
if DoesBlipExist(waypoint) then
|
|
local coords = GetBlipInfoIdCoord(waypoint)
|
|
local distance = CalculateDistance(coords) / 1000
|
|
local price = math.max(Config.MinFare, math.ceil(distance * pricePerKm))
|
|
StartMobileTaxiRide(coords, price)
|
|
else
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Du hast keinen Waypoint gesetzt',
|
|
type = 'error'
|
|
})
|
|
OpenMobileTaxiMenu(pricePerKm)
|
|
end
|
|
end
|
|
})
|
|
|
|
-- Aussteigen Option
|
|
table.insert(options, {
|
|
title = 'Aussteigen',
|
|
description = 'Das Taxi verlassen',
|
|
icon = 'door-open',
|
|
onSelect = function()
|
|
ExitMobileTaxi()
|
|
end
|
|
})
|
|
|
|
lib.registerContext({
|
|
id = 'mobile_taxi_menu',
|
|
title = 'Taxi - Ziel wählen',
|
|
options = options
|
|
})
|
|
|
|
lib.showContext('mobile_taxi_menu')
|
|
end
|
|
|
|
function StartMobileTaxiRide(destination, price)
|
|
if not currentTaxi or not taxiDriver then
|
|
print("^1[TAXI DEBUG]^7 No taxi or driver for ride")
|
|
return
|
|
end
|
|
|
|
print("^2[TAXI DEBUG]^7 Starting taxi ride to: " .. tostring(destination))
|
|
currentFare = price
|
|
meterRunning = true
|
|
|
|
-- Destination Blip erstellen
|
|
destinationBlip = AddBlipForCoord(destination.x, destination.y, destination.z)
|
|
SetBlipSprite(destinationBlip, 1)
|
|
SetBlipColour(destinationBlip, 2)
|
|
SetBlipScale(destinationBlip, 0.8)
|
|
BeginTextCommandSetBlipName("STRING")
|
|
AddTextComponentString("Taxi Ziel")
|
|
EndTextCommandSetBlipName(destinationBlip)
|
|
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Fahrt gestartet - Preis: $' .. price,
|
|
type = 'success'
|
|
})
|
|
|
|
-- Zum Ziel fahren
|
|
TaskVehicleDriveToCoord(taxiDriver, currentTaxi, destination.x, destination.y, destination.z, 25.0, 0, GetEntityModel(currentTaxi), 786603, 1.0, true)
|
|
|
|
-- Überwachen der Fahrt
|
|
CreateThread(function()
|
|
while meterRunning and currentTaxi do
|
|
local taxiCoords = GetEntityCoords(currentTaxi)
|
|
local distance = #(vector3(destination.x, destination.y, destination.z) - taxiCoords)
|
|
|
|
if distance < 10.0 then
|
|
TaskVehicleTempAction(taxiDriver, currentTaxi, 27, 3000)
|
|
|
|
print("^2[TAXI DEBUG]^7 Arrived at destination")
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Du bist angekommen! Preis: $' .. currentFare,
|
|
type = 'success'
|
|
})
|
|
|
|
TriggerServerEvent('taxi:payFare', currentFare)
|
|
|
|
SetTimeout(10000, function()
|
|
CleanupMobileTaxi()
|
|
end)
|
|
|
|
break
|
|
end
|
|
|
|
Wait(2000)
|
|
end
|
|
end)
|
|
end
|
|
|
|
function CalculateDistance(coords)
|
|
local playerCoords = GetEntityCoords(PlayerPedId())
|
|
return #(playerCoords - coords)
|
|
end
|
|
|
|
function ExitMobileTaxi()
|
|
print("^2[TAXI DEBUG]^7 Player exiting taxi")
|
|
local playerPed = PlayerPedId()
|
|
TaskLeaveVehicle(playerPed, currentTaxi, 0)
|
|
|
|
lib.notify({
|
|
title = 'Taxi Service',
|
|
description = 'Du bist ausgestiegen',
|
|
type = 'info'
|
|
})
|
|
|
|
SetTimeout(5000, function()
|
|
CleanupMobileTaxi()
|
|
end)
|
|
end
|
|
|
|
function CleanupMobileTaxi()
|
|
print("^2[TAXI DEBUG]^7 Cleaning up mobile taxi")
|
|
meterRunning = false
|
|
inTaxi = false
|
|
|
|
if taxiBlip then
|
|
RemoveBlip(taxiBlip)
|
|
taxiBlip = nil
|
|
end
|
|
|
|
if destinationBlip then
|
|
RemoveBlip(destinationBlip)
|
|
destinationBlip = nil
|
|
end
|
|
|
|
if currentTaxi then
|
|
if taxiDriver then
|
|
DeleteEntity(taxiDriver)
|
|
taxiDriver = nil
|
|
end
|
|
DeleteEntity(currentTaxi)
|
|
currentTaxi = nil
|
|
end
|
|
end
|
|
|
|
-- Menu erneut öffnen wenn im Mobile Taxi
|
|
CreateThread(function()
|
|
while true do
|
|
if inTaxi and currentTaxi and not meterRunning then
|
|
if IsControlJustPressed(0, 38) then -- E Taste
|
|
local selectedVehicle = nil
|
|
local vehicleModel = GetEntityModel(currentTaxi)
|
|
|
|
for _, vehicle in pairs(Config.TaxiVehicles) do
|
|
if GetHashKey(vehicle.model) == vehicleModel then
|
|
selectedVehicle = vehicle
|
|
break
|
|
end
|
|
end
|
|
|
|
if selectedVehicle then
|
|
OpenMobileTaxiMenu(selectedVehicle.pricePerKm)
|
|
end
|
|
end
|
|
|
|
lib.showTextUI('[E] - Ziel wählen')
|
|
else
|
|
lib.hideTextUI()
|
|
end
|
|
|
|
Wait(0)
|
|
end
|
|
end)
|
|
|
|
-- Cleanup beim Disconnect
|
|
AddEventHandler('onResourceStop', function(resourceName)
|
|
if GetCurrentResourceName() == resourceName then
|
|
CleanupMobileTaxi()
|
|
end
|
|
end)
|