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