diff --git a/resources/[tools]/nordi_taxi/client/main.lua b/resources/[tools]/nordi_taxi/client/main.lua new file mode 100644 index 000000000..608569a8b --- /dev/null +++ b/resources/[tools]/nordi_taxi/client/main.lua @@ -0,0 +1,363 @@ +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 + +-- Taxi rufen Command (Mobile Taxi) +RegisterCommand('taxi', function() + local currentTime = GetGameTimer() + if currentTime - lastTaxiCall < (Config.TaxiCallCooldown * 1000) then + local remainingTime = math.ceil((Config.TaxiCallCooldown * 1000 - (currentTime - lastTaxiCall)) / 1000) + lib.notify({ + title = 'Taxi Service', + description = 'Du musst noch ' .. remainingTime .. ' Sekunden warten', + type = 'error' + }) + return + end + + if currentTaxi then + lib.notify({ + title = 'Taxi Service', + description = 'Du hast bereits ein Taxi gerufen', + type = 'error' + }) + return + end + + CallMobileTaxi() +end) + +function CallMobileTaxi() + lastTaxiCall = GetGameTimer() + + lib.notify({ + title = 'Taxi Service', + description = 'Ein Taxi wurde gerufen und ist auf dem Weg zu dir', + type = 'success' + }) + + CreateThread(function() + local playerPed = PlayerPedId() + local playerCoords = GetEntityCoords(playerPed) + + -- Zufällige Spawn-Location wählen + local spawnLocation = Config.MobileTaxiSpawns[math.random(#Config.MobileTaxiSpawns)] + + -- Zufälliges Taxi-Fahrzeug wählen + local selectedVehicle = SelectRandomTaxi() + + -- Fahrzeug spawnen + local vehicleHash = GetHashKey(selectedVehicle.model) + RequestModel(vehicleHash) + while not HasModelLoaded(vehicleHash) do + Wait(100) + end + + currentTaxi = CreateVehicle(vehicleHash, spawnLocation.x, spawnLocation.y, spawnLocation.z, spawnLocation.w, true, false) + SetEntityAsMissionEntity(currentTaxi, true, true) + SetVehicleOnGroundProperly(currentTaxi) + + -- Fahrer spawnen + local driverHash = GetHashKey("a_m_m_taxi_01") + RequestModel(driverHash) + while not HasModelLoaded(driverHash) do + Wait(100) + end + + taxiDriver = CreatePedInsideVehicle(currentTaxi, 26, driverHash, -1, true, false) + 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) + + -- Zum Spieler fahren + TaskVehicleDriveToCoord(taxiDriver, currentTaxi, playerCoords.x, playerCoords.y, playerCoords.z, 20.0, 0, vehicleHash, 786603, 1.0, true) + + -- Warten bis Taxi ankommt + local arrived = false + local timeout = GetGameTimer() + (Config.MaxWaitTime * 1000) + + while not arrived and GetGameTimer() < timeout do + local taxiCoords = GetEntityCoords(currentTaxi) + local distance = #(playerCoords - taxiCoords) + + if distance < 10.0 then + arrived = true + TaskVehicleTempAction(taxiDriver, currentTaxi, 27, 3000) + + 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 + lib.notify({ + title = 'Taxi Service', + description = 'Das Taxi konnte dich nicht erreichen', + type = 'error' + }) + CleanupMobileTaxi() + end + end) +end + +function SelectRandomTaxi() + 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) + CreateThread(function() + local timeout = GetGameTimer() + 60000 + + while currentTaxi and GetGameTimer() < timeout do + local playerPed = PlayerPedId() + + if IsPedInVehicle(playerPed, currentTaxi, false) then + inTaxi = true + OpenMobileTaxiMenu(pricePerKm) + break + end + + Wait(1000) + end + + if not inTaxi then + lib.notify({ + title = 'Taxi Service', + description = 'Das Taxi ist weggefahren', + type = 'error' + }) + CleanupMobileTaxi() + end + end) +end + +function OpenMobileTaxiMenu(pricePerKm) + 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 return end + + 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) + + 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() + 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() + 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) diff --git a/resources/[tools]/nordi_taxi/client/stations.lua b/resources/[tools]/nordi_taxi/client/stations.lua new file mode 100644 index 000000000..88c2275a3 --- /dev/null +++ b/resources/[tools]/nordi_taxi/client/stations.lua @@ -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) diff --git a/resources/[tools]/nordi_taxi/config.lua b/resources/[tools]/nordi_taxi/config.lua new file mode 100644 index 000000000..04f49ea89 --- /dev/null +++ b/resources/[tools]/nordi_taxi/config.lua @@ -0,0 +1,178 @@ +Config = {} + +-- Taxi Fahrzeuge und Preise +Config.TaxiVehicles = { + { + model = 'taxi', + label = 'Standard Taxi', + pricePerKm = 5, + spawnChance = 70 + }, + { + model = 'stretch', + label = 'Luxus Limousine', + pricePerKm = 15, + spawnChance = 20 + }, + { + model = 'superd', + label = 'Premium Taxi', + pricePerKm = 10, + spawnChance = 10 + } +} + +-- Taxi Stationen mit festen Fahrzeugen +Config.TaxiStations = { + { + name = "Los Santos Airport Taxi", + coords = vector4(-1041.51, -2730.2, 20.17, 240.0), + blipCoords = vector3(-1041.51, -2730.2, 20.17), + vehicles = { + { + model = 'taxi', + coords = vector4(-1041.51, -2730.2, 20.17, 240.0), + pricePerKm = 5 + }, + { + model = 'stretch', + coords = vector4(-1045.0, -2732.0, 20.17, 240.0), + pricePerKm = 15 + } + } + }, + { + name = "Downtown Taxi Stand", + coords = vector4(895.46, -179.28, 74.7, 240.0), + blipCoords = vector3(895.46, -179.28, 74.7), + vehicles = { + { + model = 'taxi', + coords = vector4(895.46, -179.28, 74.7, 240.0), + pricePerKm = 5 + }, + { + model = 'superd', + coords = vector4(892.0, -181.0, 74.7, 240.0), + pricePerKm = 10 + } + } + }, + { + name = "Mirror Park Taxi", + coords = vector4(1696.62, 4785.41, 42.02, 90.0), + blipCoords = vector3(1696.62, 4785.41, 42.02), + vehicles = { + { + model = 'taxi', + coords = vector4(1696.62, 4785.41, 42.02, 90.0), + pricePerKm = 5 + } + } + }, + { + name = "Paleto Bay Taxi", + coords = vector4(-348.88, 6063.5, 31.5, 225.0), + blipCoords = vector3(-348.88, 6063.5, 31.5), + vehicles = { + { + model = 'taxi', + coords = vector4(-348.88, 6063.5, 31.5, 225.0), + pricePerKm = 6 + } + } + }, + { + name = "Stadtpark Taxi", + coords = vector4(218.13, -917.98, 29.6, 343.32), + blipCoords = vector3(218.13, -917.98, 29.6), + vehicles = { + { + model = 'taxi', + coords = vector4(218.13, -917.98, 29.6, 343.32), + pricePerKm = 6 + } + } + }, + + + + + { + name = "Vespucci Beach Taxi", + coords = vector4(-1266.53, -833.8, 17.11, 37.5), + blipCoords = vector3(-1266.53, -833.8, 17.11), + vehicles = { + { + model = 'taxi', + coords = vector4(-1266.53, -833.8, 17.11, 37.5), + pricePerKm = 5 + }, + { + model = 'stretch', + coords = vector4(-1270.0, -830.0, 17.11, 37.5), + pricePerKm = 15 + } + } + } +} + +-- Spawn Locations für /taxi Command (mobile Taxis) +Config.MobileTaxiSpawns = { + vector4(-1041.51, -2730.2, 20.17, 240.0), + vector4(895.46, -179.28, 74.7, 240.0), + vector4(-1266.53, -833.8, 17.11, 37.5), + vector4(1696.62, 4785.41, 42.02, 90.0), + vector4(-348.88, 6063.5, 31.5, 225.0) +} + +-- Bekannte Ziele mit festen Preisen +Config.KnownDestinations = { + { + name = "Los Santos International Airport", + coords = vector3(-1037.0, -2674.0, 13.8), + price = 50 + }, + { + name = "Vinewood Hills", + coords = vector3(120.0, 564.0, 184.0), + price = 35 + }, + { + name = "Del Perro Pier", + coords = vector3(-1850.0, -1230.0, 13.0), + price = 25 + }, + { + name = "Sandy Shores", + coords = vector3(1836.0, 3672.0, 34.0), + price = 75 + }, + { + name = "Paleto Bay", + coords = vector3(-276.0, 6635.0, 7.5), + price = 100 + }, + { + name = "Mount Chiliad", + coords = vector3(501.0, 5604.0, 797.0), + price = 120 + }, + { + name = "Maze Bank Tower", + coords = vector3(-75.0, -818.0, 326.0), + price = 40 + }, + { + name = "Vespucci Beach", + coords = vector3(-1266.0, -833.0, 17.0), + price = 30 + } +} + +-- Allgemeine Einstellungen +Config.MaxWaitTime = 120 -- Sekunden bis Taxi spawnt +Config.TaxiCallCooldown = 30 -- Sekunden zwischen Taxi-Rufen +Config.MinFare = 10 -- Mindestpreis +Config.WaitingFee = 2 -- Preis pro Minute warten +Config.StationTaxiRespawnTime = 300 -- 5 Minuten bis Taxi an Station respawnt diff --git a/resources/[tools]/nordi_taxi/fxmanifest.lua b/resources/[tools]/nordi_taxi/fxmanifest.lua new file mode 100644 index 000000000..e69de29bb diff --git a/resources/[tools]/nordi_taxi/server/main.lua b/resources/[tools]/nordi_taxi/server/main.lua new file mode 100644 index 000000000..33763a698 --- /dev/null +++ b/resources/[tools]/nordi_taxi/server/main.lua @@ -0,0 +1,48 @@ +local QBCore = exports['qb-core']:GetCoreObject() + +RegisterNetEvent('taxi:payFare', function(amount) + local src = source + local Player = QBCore.Functions.GetPlayer(src) + + if not Player then return end + + local playerMoney = Player.PlayerData.money.cash + + if playerMoney >= amount then + Player.Functions.RemoveMoney('cash', amount, 'taxi-fare') + TriggerClientEvent('QBCore:Notify', src, 'Du hast $' .. amount .. ' für die Taxifahrt bezahlt', 'success') + + -- Log für Admin + print('^2[TAXI]^7 ' .. Player.PlayerData.name .. ' (' .. src .. ') hat $' .. amount .. ' für eine Taxifahrt bezahlt') + else + local bankMoney = Player.PlayerData.money.bank + if bankMoney >= amount then + Player.Functions.RemoveMoney('bank', amount, 'taxi-fare') + TriggerClientEvent('QBCore:Notify', src, 'Du hast $' .. amount .. ' per Karte für die Taxifahrt bezahlt', 'success') + + -- Log für Admin + print('^2[TAXI]^7 ' .. Player.PlayerData.name .. ' (' .. src .. ') hat $' .. amount .. ' per Karte für eine Taxifahrt bezahlt') + else + TriggerClientEvent('QBCore:Notify', src, 'Du hast nicht genug Geld für die Taxifahrt!', 'error') + + -- Log für Admin + print('^1[TAXI]^7 ' .. Player.PlayerData.name .. ' (' .. src .. ') konnte $' .. amount .. ' für eine Taxifahrt nicht bezahlen') + end + end +end) + +-- Admin Command zum Respawnen aller Taxi-Stationen +QBCore.Commands.Add('respawntaxis', 'Respawne alle Taxi-Stationen (Admin Only)', {}, false, function(source, args) + local Player = QBCore.Functions.GetPlayer(source) + if Player.PlayerData.job.name == 'admin' or QBCore.Functions.HasPermission(source, 'admin') then + TriggerClientEvent('taxi:respawnAllStations', -1) + TriggerClientEvent('QBCore:Notify', source, 'Alle Taxi-Stationen wurden respawnt', 'success') + else + TriggerClientEvent('QBCore:Notify', source, 'Du hast keine Berechtigung für diesen Befehl', 'error') + end +end, 'admin') + +-- Event für das Respawnen der Stationen +RegisterNetEvent('taxi:respawnAllStations', function() + -- Wird an alle Clients gesendet +end)