ed
This commit is contained in:
		
							parent
							
								
									bfca08b472
								
							
						
					
					
						commit
						e3b92cca6f
					
				
					 5 changed files with 921 additions and 0 deletions
				
			
		
							
								
								
									
										332
									
								
								resources/[tools]/nordi_taxi/client/stations.lua
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										332
									
								
								resources/[tools]/nordi_taxi/client/stations.lua
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,332 @@ | |||
| local QBCore = exports['qb-core']:GetCoreObject() | ||||
| local stationVehicles = {} | ||||
| local stationBlips = {} | ||||
|  | ||||
| -- Taxi Stationen initialisieren | ||||
| CreateThread(function() | ||||
|     Wait(1000) | ||||
|     InitializeTaxiStations() | ||||
| end) | ||||
|  | ||||
| function InitializeTaxiStations() | ||||
|     for stationId, station in pairs(Config.TaxiStations) do | ||||
|         -- Blip für Station erstellen | ||||
|         local blip = AddBlipForCoord(station.blipCoords.x, station.blipCoords.y, station.blipCoords.z) | ||||
|         SetBlipSprite(blip, 198) | ||||
|         SetBlipColour(blip, 5) | ||||
|         SetBlipScale(blip, 0.8) | ||||
|         SetBlipAsShortRange(blip, true) | ||||
|         BeginTextCommandSetBlipName("STRING") | ||||
|         AddTextComponentString(station.name) | ||||
|         EndTextCommandSetBlipName(blip) | ||||
|         stationBlips[stationId] = blip | ||||
|          | ||||
|         -- Fahrzeuge an Station spawnen | ||||
|         stationVehicles[stationId] = {} | ||||
|         for vehicleId, vehicleData in pairs(station.vehicles) do | ||||
|             SpawnStationVehicle(stationId, vehicleId, vehicleData) | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| function SpawnStationVehicle(stationId, vehicleId, vehicleData) | ||||
|     CreateThread(function() | ||||
|         local vehicleHash = GetHashKey(vehicleData.model) | ||||
|         RequestModel(vehicleHash) | ||||
|         while not HasModelLoaded(vehicleHash) do | ||||
|             Wait(100) | ||||
|         end | ||||
|  | ||||
|         local vehicle = CreateVehicle( | ||||
|             vehicleHash,  | ||||
|             vehicleData.coords.x,  | ||||
|             vehicleData.coords.y,  | ||||
|             vehicleData.coords.z,  | ||||
|             vehicleData.coords.w,  | ||||
|             false,  | ||||
|             false | ||||
|         ) | ||||
|          | ||||
|         SetEntityAsMissionEntity(vehicle, true, true) | ||||
|         SetVehicleOnGroundProperly(vehicle) | ||||
|         SetVehicleDoorsLocked(vehicle, 2) -- Locked | ||||
|         SetVehicleEngineOn(vehicle, false, true, false) | ||||
|          | ||||
|         -- Fahrzeug-Info speichern | ||||
|         stationVehicles[stationId][vehicleId] = { | ||||
|             entity = vehicle, | ||||
|             data = vehicleData, | ||||
|             occupied = false | ||||
|         } | ||||
|          | ||||
|         -- qb-target für Fahrzeug hinzufügen | ||||
|         exports['qb-target']:AddTargetEntity(vehicle, { | ||||
|             options = { | ||||
|                 { | ||||
|                     type = "client", | ||||
|                     event = "taxi:enterStationVehicle", | ||||
|                     icon = "fas fa-taxi", | ||||
|                     label = "Taxi nehmen ($" .. vehicleData.pricePerKm .. "/km)", | ||||
|                     stationId = stationId, | ||||
|                     vehicleId = vehicleId | ||||
|                 } | ||||
|             }, | ||||
|             distance = 3.0 | ||||
|         }) | ||||
|          | ||||
|         SetModelAsNoLongerNeeded(vehicleHash) | ||||
|     end) | ||||
| end | ||||
|  | ||||
| -- Event für Einsteigen in Station-Taxi | ||||
| RegisterNetEvent('taxi:enterStationVehicle', function(data) | ||||
|     local stationId = data.stationId | ||||
|     local vehicleId = data.vehicleId | ||||
|      | ||||
|     if not stationVehicles[stationId] or not stationVehicles[stationId][vehicleId] then | ||||
|         lib.notify({ | ||||
|             title = 'Taxi Service', | ||||
|             description = 'Dieses Taxi ist nicht verfügbar', | ||||
|             type = 'error' | ||||
|         }) | ||||
|         return | ||||
|     end | ||||
|      | ||||
|     local vehicleInfo = stationVehicles[stationId][vehicleId] | ||||
|      | ||||
|     if vehicleInfo.occupied then | ||||
|         lib.notify({ | ||||
|             title = 'Taxi Service', | ||||
|             description = 'Dieses Taxi ist bereits besetzt', | ||||
|             type = 'error' | ||||
|         }) | ||||
|         return | ||||
|     end | ||||
|      | ||||
|     -- Spieler ins Fahrzeug setzen | ||||
|     local playerPed = PlayerPedId() | ||||
|     local vehicle = vehicleInfo.entity | ||||
|      | ||||
|     -- Türen entsperren | ||||
|     SetVehicleDoorsLocked(vehicle, 1) | ||||
|      | ||||
|     -- Fahrer spawnen | ||||
|     local driverHash = GetHashKey("a_m_m_taxi_01") | ||||
|     RequestModel(driverHash) | ||||
|     while not HasModelLoaded(driverHash) do | ||||
|         Wait(100) | ||||
|     end | ||||
|  | ||||
|     local driver = CreatePedInsideVehicle(vehicle, 26, driverHash, -1, true, false) | ||||
|     SetEntityAsMissionEntity(driver, true, true) | ||||
|     SetPedFleeAttributes(driver, 0, 0) | ||||
|     SetPedCombatAttributes(driver, 17, 1) | ||||
|     SetPedSeeingRange(driver, 0.0) | ||||
|     SetPedHearingRange(driver, 0.0) | ||||
|     SetPedAlertness(driver, 0) | ||||
|     SetPedKeepTask(driver, true) | ||||
|      | ||||
|     -- Spieler einsteigen lassen | ||||
|     TaskEnterVehicle(playerPed, vehicle, 10000, 0, 1.0, 1, 0) | ||||
|      | ||||
|     -- Warten bis Spieler eingestiegen ist | ||||
|     CreateThread(function() | ||||
|         local timeout = GetGameTimer() + 10000 | ||||
|         while GetGameTimer() < timeout do | ||||
|             if IsPedInVehicle(playerPed, vehicle, false) then | ||||
|                 vehicleInfo.occupied = true | ||||
|                 vehicleInfo.driver = driver | ||||
|                  | ||||
|                 -- Ziel-Menu öffnen | ||||
|                 OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, vehicleInfo.data.pricePerKm) | ||||
|                 break | ||||
|             end | ||||
|             Wait(100) | ||||
|         end | ||||
|     end) | ||||
| end) | ||||
|  | ||||
| function OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, pricePerKm) | ||||
|     local options = {} | ||||
|      | ||||
|     -- Bekannte Ziele hinzufügen | ||||
|     for _, destination in pairs(Config.KnownDestinations) do | ||||
|         local customPrice = math.max(Config.MinFare, math.ceil((CalculateDistanceToCoords(destination.coords) / 1000) * pricePerKm)) | ||||
|         table.insert(options, { | ||||
|             title = destination.name, | ||||
|             description = 'Preis: $' .. customPrice, | ||||
|             icon = 'map-marker', | ||||
|             onSelect = function() | ||||
|                 StartStationTaxiRide(stationId, vehicleId, vehicle, driver, 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 = CalculateDistanceToCoords(coords) / 1000 | ||||
|                 local price = math.max(Config.MinFare, math.ceil(distance * pricePerKm)) | ||||
|                 StartStationTaxiRide(stationId, vehicleId, vehicle, driver, coords, price) | ||||
|             else | ||||
|                 lib.notify({ | ||||
|                     title = 'Taxi Service', | ||||
|                     description = 'Du hast keinen Waypoint gesetzt', | ||||
|                     type = 'error' | ||||
|                 }) | ||||
|                 OpenStationTaxiMenu(stationId, vehicleId, vehicle, driver, pricePerKm) | ||||
|             end | ||||
|         end | ||||
|     }) | ||||
|      | ||||
|     -- Aussteigen Option | ||||
|     table.insert(options, { | ||||
|         title = 'Aussteigen', | ||||
|         description = 'Das Taxi verlassen', | ||||
|         icon = 'door-open', | ||||
|         onSelect = function() | ||||
|             ExitStationTaxi(stationId, vehicleId, vehicle, driver) | ||||
|         end | ||||
|     }) | ||||
|  | ||||
|     lib.registerContext({ | ||||
|         id = 'station_taxi_menu', | ||||
|         title = 'Taxi - Ziel wählen', | ||||
|         options = options | ||||
|     }) | ||||
|  | ||||
|     lib.showContext('station_taxi_menu') | ||||
| end | ||||
|  | ||||
| function StartStationTaxiRide(stationId, vehicleId, vehicle, driver, destination, price) | ||||
|     lib.notify({ | ||||
|         title = 'Taxi Service', | ||||
|         description = 'Fahrt gestartet - Preis: $' .. price, | ||||
|         type = 'success' | ||||
|     }) | ||||
|      | ||||
|     -- Destination Blip erstellen | ||||
|     local 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) | ||||
|      | ||||
|     -- Zum Ziel fahren | ||||
|     TaskVehicleDriveToCoord(driver, vehicle, destination.x, destination.y, destination.z, 25.0, 0, GetEntityModel(vehicle), 786603, 1.0, true) | ||||
|      | ||||
|     -- Fahrt überwachen | ||||
|     CreateThread(function() | ||||
|         while DoesEntityExist(vehicle) and DoesEntityExist(driver) do | ||||
|             local vehicleCoords = GetEntityCoords(vehicle) | ||||
|             local distance = #(vector3(destination.x, destination.y, destination.z) - vehicleCoords) | ||||
|              | ||||
|             if distance < 10.0 then | ||||
|                 -- Angekommen | ||||
|                 TaskVehicleTempAction(driver, vehicle, 27, 3000) | ||||
|                  | ||||
|                 lib.notify({ | ||||
|                     title = 'Taxi Service', | ||||
|                     description = 'Du bist angekommen! Preis: $' .. price, | ||||
|                     type = 'success' | ||||
|                 }) | ||||
|                  | ||||
|                 -- Bezahlung | ||||
|                 TriggerServerEvent('taxi:payFare', price) | ||||
|                  | ||||
|                 -- Blip entfernen | ||||
|                 RemoveBlip(destinationBlip) | ||||
|                  | ||||
|                 -- Nach 10 Sekunden Taxi zurück zur Station | ||||
|                 SetTimeout(10000, function() | ||||
|                     ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) | ||||
|                 end) | ||||
|                  | ||||
|                 break | ||||
|             end | ||||
|              | ||||
|             Wait(2000) | ||||
|         end | ||||
|     end) | ||||
| end | ||||
|  | ||||
| function ExitStationTaxi(stationId, vehicleId, vehicle, driver) | ||||
|     local playerPed = PlayerPedId() | ||||
|     TaskLeaveVehicle(playerPed, vehicle, 0) | ||||
|      | ||||
|     lib.notify({ | ||||
|         title = 'Taxi Service', | ||||
|         description = 'Du bist ausgestiegen', | ||||
|         type = 'info' | ||||
|     }) | ||||
|      | ||||
|     -- Taxi zurück zur Station nach 5 Sekunden | ||||
|     SetTimeout(5000, function() | ||||
|         ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) | ||||
|     end) | ||||
| end | ||||
|  | ||||
| function ReturnTaxiToStation(stationId, vehicleId, vehicle, driver) | ||||
|     if not stationVehicles[stationId] or not stationVehicles[stationId][vehicleId] then | ||||
|         return | ||||
|     end | ||||
|      | ||||
|     -- Fahrer löschen | ||||
|     if DoesEntityExist(driver) then | ||||
|         DeleteEntity(driver) | ||||
|     end | ||||
|      | ||||
|     -- Fahrzeug löschen | ||||
|     if DoesEntityExist(vehicle) then | ||||
|         exports['qb-target']:RemoveTargetEntity(vehicle) | ||||
|         DeleteEntity(vehicle) | ||||
|     end | ||||
|      | ||||
|     -- Fahrzeug als nicht besetzt markieren | ||||
|     stationVehicles[stationId][vehicleId].occupied = false | ||||
|     stationVehicles[stationId][vehicleId].driver = nil | ||||
|      | ||||
|     -- Nach Respawn-Zeit neues Fahrzeug spawnen | ||||
|     SetTimeout(Config.StationTaxiRespawnTime * 1000, function() | ||||
|         if stationVehicles[stationId] and stationVehicles[stationId][vehicleId] then | ||||
|             local vehicleData = stationVehicles[stationId][vehicleId].data | ||||
|             SpawnStationVehicle(stationId, vehicleId, vehicleData) | ||||
|         end | ||||
|     end) | ||||
| end | ||||
|  | ||||
| function CalculateDistanceToCoords(coords) | ||||
|     local playerCoords = GetEntityCoords(PlayerPedId()) | ||||
|     return #(playerCoords - coords) | ||||
| end | ||||
|  | ||||
| -- Cleanup beim Resource Stop | ||||
| AddEventHandler('onResourceStop', function(resourceName) | ||||
|     if GetCurrentResourceName() == resourceName then | ||||
|         -- Alle Station-Fahrzeuge löschen | ||||
|         for stationId, vehicles in pairs(stationVehicles) do | ||||
|             for vehicleId, vehicleInfo in pairs(vehicles) do | ||||
|                 if DoesEntityExist(vehicleInfo.entity) then | ||||
|                     exports['qb-target']:RemoveTargetEntity(vehicleInfo.entity) | ||||
|                     DeleteEntity(vehicleInfo.entity) | ||||
|                 end | ||||
|                 if vehicleInfo.driver and DoesEntityExist(vehicleInfo.driver) then | ||||
|                     DeleteEntity(vehicleInfo.driver) | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|          | ||||
|         -- Alle Blips entfernen | ||||
|         for _, blip in pairs(stationBlips) do | ||||
|             RemoveBlip(blip) | ||||
|         end | ||||
|     end | ||||
| end) | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nordi98
						Nordi98