277 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
	
		
			9.2 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
-- client.lua
 | 
						|
local QBCore = exports['qb-core']:GetCoreObject()
 | 
						|
local activeZones = {}
 | 
						|
local spawnedProps = {}
 | 
						|
local processedVehicles = {}
 | 
						|
local menu = false
 | 
						|
 | 
						|
-- Debug Funktion
 | 
						|
function DebugPrint(text)
 | 
						|
    if Config.Debug then
 | 
						|
        print('[Traffic Control] ' .. tostring(text))
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-- Hotkey Registration
 | 
						|
RegisterKeyMapping('trafficmenu', 'Öffne Verkehrssteuerung', 'keyboard', Config.Hotkey)
 | 
						|
 | 
						|
RegisterCommand('trafficmenu', function()
 | 
						|
    local job = QBCore.Functions.GetPlayerData().job
 | 
						|
    if Config.AllowedJobs[job.name] then
 | 
						|
        ToggleMenu()
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
function ToggleMenu()
 | 
						|
    if menu then
 | 
						|
        CloseMenu()
 | 
						|
    else
 | 
						|
        OpenMenu()
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function OpenMenu()
 | 
						|
    if menu then return end
 | 
						|
    
 | 
						|
    local job = QBCore.Functions.GetPlayerData().job
 | 
						|
    if not Config.AllowedJobs[job.name] then 
 | 
						|
        DebugPrint('Keine Berechtigung für Job: ' .. job.name)
 | 
						|
        return 
 | 
						|
    end
 | 
						|
 | 
						|
    menu = true
 | 
						|
    SendNUIMessage({
 | 
						|
        action = "open",
 | 
						|
        items = Config.Items
 | 
						|
    })
 | 
						|
    SetNuiFocus(true, true)
 | 
						|
    DebugPrint('Menü geöffnet')
 | 
						|
end
 | 
						|
 | 
						|
function CloseMenu()
 | 
						|
    menu = false
 | 
						|
    SetNuiFocus(false, false)
 | 
						|
    SendNUIMessage({
 | 
						|
        action = "close"
 | 
						|
    })
 | 
						|
    DebugPrint('Menü geschlossen')
 | 
						|
end
 | 
						|
 | 
						|
RegisterNUICallback('closeMenu', function(data, cb)
 | 
						|
    CloseMenu()
 | 
						|
    cb('ok')
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNUICallback('setPoint', function(data, cb)
 | 
						|
    local coords = GetEntityCoords(PlayerPedId())
 | 
						|
    local radius = tonumber(data.radius) or 30.0
 | 
						|
    
 | 
						|
    local zone = {
 | 
						|
        coords = coords,
 | 
						|
        radius = radius
 | 
						|
    }
 | 
						|
    
 | 
						|
    table.insert(activeZones, zone)
 | 
						|
    spawnBarrier(coords, data.item)
 | 
						|
    
 | 
						|
    CloseMenu()
 | 
						|
    DebugPrint('Punkt gesetzt bei ' .. vec3(coords.x, coords.y, coords.z))
 | 
						|
    cb('ok')
 | 
						|
end)
 | 
						|
 | 
						|
function spawnBarrier(coords, itemModel)
 | 
						|
    DebugPrint('Versuche Barriere zu spawnen: ' .. itemModel)
 | 
						|
    local prop = CreateObject(GetHashKey(itemModel), coords.x, coords.y, coords.z - 1.0, true, false, false)
 | 
						|
    if prop and DoesEntityExist(prop) then
 | 
						|
        PlaceObjectOnGroundProperly(prop)
 | 
						|
        FreezeEntityPosition(prop, true)
 | 
						|
        table.insert(spawnedProps, prop)
 | 
						|
        DebugPrint('Barriere erfolgreich gespawnt')
 | 
						|
    else
 | 
						|
        DebugPrint('Fehler beim Spawnen der Barriere')
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-- NPC Steuerung
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(100)
 | 
						|
 | 
						|
        if #activeZones == 0 then 
 | 
						|
            Citizen.Wait(1000)
 | 
						|
            goto continue 
 | 
						|
        end
 | 
						|
 | 
						|
        for _, zone in pairs(activeZones) do
 | 
						|
            local vehicles = GetGamePool('CVehicle')
 | 
						|
            
 | 
						|
            for _, vehicle in pairs(vehicles) do
 | 
						|
                if DoesEntityExist(vehicle) then
 | 
						|
                    local vehicleCoords = GetEntityCoords(vehicle)
 | 
						|
                    local distance = #(vehicleCoords - zone.coords)
 | 
						|
                    local detectionRange = zone.radius + 30.0 -- Erkennung 30 Meter vor der Zone
 | 
						|
 | 
						|
                    if distance <= detectionRange and not processedVehicles[vehicle] then
 | 
						|
                        local driver = GetPedInVehicleSeat(vehicle, -1)
 | 
						|
                        
 | 
						|
                        if DoesEntityExist(driver) and not IsPedAPlayer(driver) then
 | 
						|
                            processedVehicles[vehicle] = true
 | 
						|
                            
 | 
						|
                            -- Bremse das Fahrzeug
 | 
						|
                            SetVehicleForwardSpeed(vehicle, 0.0)
 | 
						|
                            TaskVehicleTempAction(driver, vehicle, 27, 1000) -- Bremsaktion
 | 
						|
                            
 | 
						|
                            -- Warte kurz
 | 
						|
                            Citizen.Wait(1000)
 | 
						|
                            
 | 
						|
                            -- Hole aktuelle Position und Heading
 | 
						|
                            local currentHeading = GetEntityHeading(vehicle)
 | 
						|
                            
 | 
						|
                            -- Drehe um 180 Grad
 | 
						|
                            local newHeading = currentHeading + 180.0
 | 
						|
                            if newHeading > 360.0 then 
 | 
						|
                                newHeading = newHeading - 360.0 
 | 
						|
                            end
 | 
						|
                            
 | 
						|
                            -- Führe die Drehung aus
 | 
						|
                            TaskVehicleTempAction(driver, vehicle, 6, 2000) -- Drehe nach links
 | 
						|
                            
 | 
						|
                            -- Warte auf Drehung
 | 
						|
                            Citizen.Wait(2000)
 | 
						|
                            
 | 
						|
                            -- Fahre weg
 | 
						|
                            local escapePoint = vector3(
 | 
						|
                                vehicleCoords.x - (math.cos(math.rad(currentHeading)) * 100.0),
 | 
						|
                                vehicleCoords.y - (math.sin(math.rad(currentHeading)) * 100.0),
 | 
						|
                                vehicleCoords.z
 | 
						|
                            )
 | 
						|
                            
 | 
						|
                            TaskVehicleDriveToCoordLongrange(
 | 
						|
                                driver,
 | 
						|
                                vehicle,
 | 
						|
                                escapePoint.x,
 | 
						|
                                escapePoint.y,
 | 
						|
                                escapePoint.z,
 | 
						|
                                20.0,    -- Geschwindigkeit
 | 
						|
                                786603,  -- Driving Style
 | 
						|
                                20.0     -- Stopping Range
 | 
						|
                            )
 | 
						|
                            
 | 
						|
                            -- Lösche Fahrzeug nach Entfernung
 | 
						|
                            Citizen.SetTimeout(8000, function()
 | 
						|
                                if DoesEntityExist(vehicle) then
 | 
						|
                                    local newDist = #(GetEntityCoords(vehicle) - zone.coords)
 | 
						|
                                    if newDist > detectionRange * 2 then
 | 
						|
                                        DeleteEntity(vehicle)
 | 
						|
                                        processedVehicles[vehicle] = nil
 | 
						|
                                    end
 | 
						|
                                end
 | 
						|
                            end)
 | 
						|
                        end
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
        
 | 
						|
        ::continue::
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Cleanup Thread für processedVehicles
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(30000)
 | 
						|
        for vehicle, _ in pairs(processedVehicles) do
 | 
						|
            if not DoesEntityExist(vehicle) then
 | 
						|
                processedVehicles[vehicle] = nil
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
 | 
						|
-- Zusätzlicher Thread für Fußgänger
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(500)
 | 
						|
 | 
						|
        if #activeZones == 0 then 
 | 
						|
            Citizen.Wait(1000)
 | 
						|
            goto continue 
 | 
						|
        end
 | 
						|
 | 
						|
        for _, zone in pairs(activeZones) do
 | 
						|
            local peds = GetGamePool('CPed')
 | 
						|
            
 | 
						|
            for _, ped in pairs(peds) do
 | 
						|
                if DoesEntityExist(ped) and not IsPedAPlayer(ped) and not IsPedInAnyVehicle(ped, false) then
 | 
						|
                    local pedCoords = GetEntityCoords(ped)
 | 
						|
                    local distance = #(pedCoords - zone.coords)
 | 
						|
 | 
						|
                    if distance <= (zone.radius + 10.0) then
 | 
						|
                        -- Berechne Fluchtrichtung
 | 
						|
                        local awayVector = vector3(
 | 
						|
                            pedCoords.x - zone.coords.x,
 | 
						|
                            pedCoords.y - zone.coords.y,
 | 
						|
                            0.0
 | 
						|
                        )
 | 
						|
                        local escapePoint = vector3(
 | 
						|
                            pedCoords.x + (awayVector.x * 2),
 | 
						|
                            pedCoords.y + (awayVector.y * 2),
 | 
						|
                            pedCoords.z
 | 
						|
                        )
 | 
						|
 | 
						|
                        -- Lasse Ped weglaufen
 | 
						|
                        ClearPedTasks(ped)
 | 
						|
                        TaskGoStraightToCoord(ped, escapePoint.x, escapePoint.y, escapePoint.z, 2.0, -1, 0.0, 0.0)
 | 
						|
                        
 | 
						|
                        -- Lösche Ped nach einer Weile
 | 
						|
                        Citizen.SetTimeout(8000, function()
 | 
						|
                            if DoesEntityExist(ped) then
 | 
						|
                                DeleteEntity(ped)
 | 
						|
                            end
 | 
						|
                        end)
 | 
						|
                    end
 | 
						|
                end
 | 
						|
            end
 | 
						|
        end
 | 
						|
 | 
						|
        ::continue::
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Cleanup Thread
 | 
						|
Citizen.CreateThread(function()
 | 
						|
    while true do
 | 
						|
        Citizen.Wait(30000)
 | 
						|
        for vehicle, _ in pairs(processedVehicles) do
 | 
						|
            if not DoesEntityExist(vehicle) then
 | 
						|
                processedVehicles[vehicle] = nil
 | 
						|
            end
 | 
						|
        end
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
-- Cleanup Command und Event
 | 
						|
RegisterCommand('trafficclean', function()
 | 
						|
    local job = QBCore.Functions.GetPlayerData().job
 | 
						|
    if Config.AllowedJobs[job.name] then
 | 
						|
        TriggerEvent('traffic:cleanup')
 | 
						|
        QBCore.Functions.Notify('Verkehrssteuerung zurückgesetzt', 'success')
 | 
						|
    end
 | 
						|
end)
 | 
						|
 | 
						|
RegisterNetEvent('traffic:cleanup')
 | 
						|
AddEventHandler('traffic:cleanup', function()
 | 
						|
    for _, prop in pairs(spawnedProps) do
 | 
						|
        if DoesEntityExist(prop) then
 | 
						|
            DeleteEntity(prop)
 | 
						|
        end
 | 
						|
    end
 | 
						|
    spawnedProps = {}
 | 
						|
    activeZones = {}
 | 
						|
    processedVehicles = {}
 | 
						|
    DebugPrint('Aufräumen abgeschlossen')
 | 
						|
end)
 | 
						|
 | 
						|
 |