2026-04-14 17:41:39 +02:00

633 lines
21 KiB
Lua

local ESX = nil
CreateThread(function()
while not ESX do
Wait(10)
ESX = exports['es_extended']:getSharedObject()
end
while ESX.GetPlayerData().job == nil do
Citizen.Wait(100)
end
ESX.PlayerData = ESX.GetPlayerData()
end)
-- ==========================================
-- BENACHRICHTIGUNGS-SYSTEM (hex_4_hud)
-- ==========================================
local function SendNotify(msg, type)
local ok, err = pcall(function()
exports['hex_4_hud']:Notify("System", msg, type or "info", 5000)
end)
if not ok then
print('[SendNotify ERROR] ' .. tostring(err))
end
end
-- ==========================================
local inRadialMenu = false
local IsDown = false
RegisterNetEvent("esx:playerLoaded")
AddEventHandler("esx:playerLoaded", function(xPlayer) ESX.PlayerData = xPlayer end)
RegisterNetEvent("esx:setJob")
AddEventHandler("esx:setJob", function(job) ESX.PlayerData.job = job end)
RegisterNetEvent('esx_ambulancejob:revive', function(pw)
IsDown = false
end)
RegisterCommand('_rad', function()
if not IsPauseMenuActive() and not inRadialMenu then
openRadial(true)
SetCursorLocation(0.5, 0.5)
end
end)
RegisterKeyMapping('_rad', 'Open Radial Menu', 'keyboard', 'F3')
local function IsPolice()
return (ESX.PlayerData.job.name == "police" or ESX.PlayerData.job.name == "sheriff")
end
AddEventHandler('esx:onPlayerDeath', function(reason)
IsDown = true
end)
local ofcDownAdded = false
function setupSubItems()
PlayerData = ESX.GetPlayerData()
if PlayerData.job.name == 'sheriff' then
PlayerData.job.name = 'police'
end
if (IsDown and IsPolice()) then
if not ofcDownAdded then
temptable = {
id = 'officerdown',
title = '10-999',
icon = 'sad-cry',
type = 'client',
event = 'pb-police:ofcdown',
shouldClose = true,
}
table.insert(Config.MenuItems, temptable)
ofcDownAdded = true
end
else
if ofcDownAdded then
for k,v in pairs(Config.MenuItems) do
if v.id == 'officerdown' then
table.remove(Config.MenuItems, k)
ofcDownAdded = false
break
end
end
end
end
if Config.JobInteractions[PlayerData.job.name] ~= nil and next(Config.JobInteractions[PlayerData.job.name]) ~= nil then
Config.MenuItems[4].items = Config.JobInteractions[PlayerData.job.name]
else
Config.MenuItems[4].items = {}
end
local Vehicle = GetVehiclePedIsIn(PlayerPedId())
if Vehicle ~= nil or Vehicle ~= 0 then
local AmountOfSeats = GetVehicleModelNumberOfSeats(GetEntityModel(Vehicle))
if AmountOfSeats == 2 then
Config.MenuItems[3].items[2].items = {
[1] = {
id = -1,
title = 'Driver',
icon = 'caret-up',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
[2] = {
id = 0,
title = 'Passenger',
icon = 'caret-up',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
}
elseif AmountOfSeats == 3 then
Config.MenuItems[3].items[2].items = {
[4] = {
id = -1,
title = 'Driver',
icon = 'caret-up',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
[1] = {
id = 0,
title = 'Passenger',
icon = 'caret-up',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
[3] = {
id = 1,
title = 'Other',
icon = 'caret-down',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
}
elseif AmountOfSeats == 4 then
Config.MenuItems[3].items[2].items = {
[4] = {
id = -1,
title = 'Driver',
icon = 'caret-up',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
[1] = {
id = 0,
title = 'Passenger',
icon = 'caret-up',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
[3] = {
id = 1,
title = 'Rear Left',
icon = 'caret-down',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
[2] = {
id = 2,
title = 'Rear Right',
icon = 'caret-down',
type = 'client',
event = 'rlo_radialmenu:client:ChangeSeat',
shouldClose = false,
},
}
end
end
end
function openRadial(bool)
setupSubItems()
SetNuiFocus(bool, bool)
SendNUIMessage({
action = "ui",
radial = bool,
items = Config.MenuItems
})
inRadialMenu = bool
end
function closeRadial(bool)
SetNuiFocus(false, false)
inRadialMenu = bool
end
RegisterNUICallback('closeRadial', function()
closeRadial(false)
end)
RegisterNUICallback('selectItem', function(data)
local itemData = data.itemData
if itemData.type == 'client' then
TriggerEvent(itemData.event, itemData)
elseif itemData.type == 'server' then
TriggerServerEvent(itemData.event, itemData)
elseif itemData.type == 'cmd' then
ExecuteCommand(itemData.event)
end
end)
RegisterNetEvent('rlo_radialmenu:client:noPlayers')
AddEventHandler('rlo_radialmenu:client:noPlayers', function(data)
SendNotify('Es ist niemand in der Nähe.', 'error')
end)
RegisterNetEvent('rlo_radialmenu:client:giveidkaart')
AddEventHandler('rlo_radialmenu:client:giveidkaart', function(data)
-- ??
end)
RegisterNetEvent('rlo_radialmenu:client:openDoor')
AddEventHandler('rlo_radialmenu:client:openDoor', function(data)
local string = data.id
local replace = string:gsub("door", "")
local door = tonumber(replace)
local ped = PlayerPedId()
local closestVehicle = nil
if IsPedInAnyVehicle(ped, false) then
closestVehicle = GetVehiclePedIsIn(ped, false)
if GetPedInVehicleSeat(closestVehicle, -1) == PlayerPedId() then
if closestVehicle ~= 0 then
if GetVehicleDoorAngleRatio(closestVehicle, door) > 0.0 then
SetVehicleDoorShut(closestVehicle, door, false)
else
SetVehicleDoorOpen(closestVehicle, door, false, false)
end
end
end
else
closestVehicle = GetClosestVehicle(GetEntityCoords(PlayerPedId()), 10.0, 0, 70)
local lockStatus = GetVehicleDoorLockStatus(closestVehicle)
if closestVehicle ~= 0 then
if lockStatus == 0 or lockStatus == 1 then --unlocked
if GetVehicleDoorAngleRatio(closestVehicle, door) > 0.0 then
SetVehicleDoorShut(closestVehicle, door, false)
else
SetVehicleDoorOpen(closestVehicle, door, false, false)
end
elseif lockStatus == 2 then -- locked
SendNotify('Fahrzeug verschlossen', 'error')
end
end
end
end)
--Rechnung--
RegisterNetEvent('rlo_radialmenu:client:billing')
AddEventHandler('rlo_radialmenu:client:billing', function()
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
if GetPedInVehicleSeat(vehicle, -1) == ped then
if GetEntitySpeed(vehicle) * 3.6 > 2 then
SendNotify('Du kannst während der Fahrt keine Rechnungen öffnen.', 'error')
return
end
end
end
-- 👉 Server aufrufen statt Client Event
TriggerServerEvent("billing:check")
end)
--MOTOR AN/AUS--
RegisterNetEvent('rlo_radialmenu:client:motor')
AddEventHandler('rlo_radialmenu:client:motor', function()
local ped = PlayerPedId()
if not IsPedInAnyVehicle(ped, false) then return end
local vehicle = GetVehiclePedIsIn(ped, false)
if GetPedInVehicleSeat(vehicle, -1) ~= ped then return end
local plate = GetVehicleNumberPlateText(vehicle)
if not exports['vehicles_keys']:doesPlayerOwnPlate(plate) then
SendNotify('Du hast keinen Schlüssel für dieses Fahrzeug.', 'error')
return
end
if GetIsVehicleEngineRunning(vehicle) then
SetVehicleEngineOn(vehicle, false, false, true)
else
SetVehicleEngineOn(vehicle, true, false, true)
end
end)
--TEMPOMAT--
RegisterNetEvent('rlo_radialmenu:client:tempomat')
AddEventHandler('rlo_radialmenu:client:tempomat', function(data)
local string = data.id
local replace = string:gsub("tempomat", "")
local tempomat = tonumber(replace)
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
if GetPedInVehicleSeat(vehicle, -1) == PlayerPedId() then
if tempomat == 1 then
SetEntityMaxSpeed(vehicle, 1000/3.6)
SendNotify('Tempomat wurde deaktiviert.', 'info')
elseif tempomat == 2 then
if GetEntitySpeed(vehicle) *3.6 < 80 then
SetEntityMaxSpeed(vehicle, 80/3.6)
SendNotify('Tempomat wurde auf 80 km/h gesetzt.', 'success')
else
SendNotify('Du musst auf die Geschwindigkeit runterbremsen!', 'error')
end
elseif tempomat == 3 then
if GetEntitySpeed(vehicle) *3.6 < 100 then
SetEntityMaxSpeed(vehicle, 100/3.6)
SendNotify('Tempomat wurde auf 100 km/h gesetzt.', 'success')
else
SendNotify('Du musst auf die Geschwindigkeit runterbremsen!', 'error')
end
elseif tempomat == 4 then
if GetEntitySpeed(vehicle) *3.6 < 130 then
SetEntityMaxSpeed(vehicle, 130/3.6)
SendNotify('Tempomat wurde auf 130 km/h gesetzt.', 'success')
else
SendNotify('Du musst auf die Geschwindigkeit runterbremsen!', 'error')
end
elseif tempomat == 5 then
if GetEntitySpeed(vehicle) *3.6 < 150 then
SetEntityMaxSpeed(vehicle, 149/3.6)
SendNotify('Tempomat wurde auf 150 km/h gesetzt.', 'success')
else
SendNotify('Du musst auf die Geschwindigkeit runterbremsen!', 'error')
end
end
end
end
end)
--FENSTER--
RegisterNetEvent('rlo_radialmenu:client:openWindow')
AddEventHandler('rlo_radialmenu:client:openWindow', function(data)
local string = data.id
local replace = string:gsub("window", "")
local window = tonumber(replace)
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
if GetPedInVehicleSeat(vehicle, -1) == PlayerPedId() then
if IsVehicleWindowIntact(vehicle, window) then
RollDownWindow(vehicle, window)
else
TriggerServerEvent('rlo_radialmenu:SetVehicleWindow', window)
end
end
end
end)
RegisterNetEvent('rlo_radialmenu:client:closeWindows')
AddEventHandler('rlo_radialmenu:client:closeWindows', function()
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
if GetPedInVehicleSeat(vehicle, -1) == PlayerPedId() then
TriggerServerEvent('rlo_radialmenu:SetAllVehicleWindows')
end
end
end)
RegisterNetEvent('rlo_radialmenu:client:closeWindow')
AddEventHandler('rlo_radialmenu:client:closeWindow', function(playerID, windowid)
local vehicle = GetVehiclePedIsIn(GetPlayerPed(GetPlayerFromServerId(playerID)), false)
RollUpWindow(vehicle, windowid)
end)
RegisterNetEvent('rlo_radialmenu:client:closeAllWindows')
AddEventHandler('rlo_radialmenu:client:closeAllWindows', function(playerID, windowid)
local vehicle = GetVehiclePedIsIn(GetPlayerPed(GetPlayerFromServerId(playerID)), false)
for i=1,4 do
local _i = i-1
RollUpWindow(vehicle, _i)
end
end)
RegisterNetEvent('rlo_radialmenu:client:openAllWindows')
AddEventHandler('rlo_radialmenu:client:openAllWindows', function()
local ped = PlayerPedId()
if IsPedInAnyVehicle(ped, false) then
local vehicle = GetVehiclePedIsIn(ped, false)
if GetPedInVehicleSeat(vehicle, -1) == PlayerPedId() then
RollDownWindows(vehicle)
end
end
end)
--FENSTER--
RegisterNetEvent('rlo_radialmenu:client:setExtra')
AddEventHandler('rlo_radialmenu:client:setExtra', function(data)
local string = data.id
local replace = string:gsub("extra", "")
local extra = tonumber(replace)
local ped = PlayerPedId()
local veh = GetVehiclePedIsIn(ped)
local enginehealth = 1000.0
local bodydamage = 1000.0
if veh ~= nil then
local plate = GetVehicleNumberPlateText(veh)
if GetPedInVehicleSeat(veh, -1) == PlayerPedId() then
if DoesExtraExist(veh, extra) then
if IsVehicleExtraTurnedOn(veh, extra) then
enginehealth = GetVehicleEngineHealth(veh)
bodydamage = GetVehicleBodyHealth(veh)
SetVehicleExtra(veh, extra, 1)
SetVehicleEngineHealth(veh, enginehealth)
SetVehicleBodyHealth(veh, bodydamage)
SendNotify('Extra ' .. extra .. ' deaktiviert.', 'error')
else
enginehealth = GetVehicleEngineHealth(veh)
bodydamage = GetVehicleBodyHealth(veh)
SetVehicleExtra(veh, extra, 0)
SetVehicleEngineHealth(veh, enginehealth)
SetVehicleBodyHealth(veh, bodydamage)
SendNotify('Extra ' .. extra .. ' aktiviert.', 'success')
end
else
SendNotify('Extra ' .. extra .. ' ist für dieses Fahrzeug nicht verfügbar.', 'error')
end
else
SendNotify('Du bist nicht der Fahrer des Fahrzeugs!', 'error')
end
end
end)
RegisterNetEvent('rlo_radialmenu:trunk:client:Door')
AddEventHandler('rlo_radialmenu:trunk:client:Door', function(plate, door, open)
local veh = GetVehiclePedIsIn(PlayerPedId())
if veh ~= 0 then
local pl = GetVehicleNumberPlateText(veh)
if pl == plate then
if open then
SetVehicleDoorOpen(veh, door, false, false)
else
SetVehicleDoorShut(veh, door, false)
end
end
end
end)
local Seats = {
["-1"] = "Fahrersitz",
["0"] = "Beifahrersitz",
["1"] = "Sitz hinten links",
["2"] = "Sitz hinten rechts",
}
RegisterNetEvent('rlo_radialmenu:client:ChangeSeat')
AddEventHandler('rlo_radialmenu:client:ChangeSeat', function(data)
local Veh = GetVehiclePedIsIn(PlayerPedId())
local IsSeatFree = IsVehicleSeatFree(Veh, data.id)
local speed = GetEntitySpeed(Veh)
-- local HasHarnass = exports['qb-smallresources']:HasHarness()
-- if not HasHarnass then
local kmh = (speed * 3.6);
if IsSeatFree then
if kmh <= 100.0 then
SetPedIntoVehicle(PlayerPedId(), Veh, data.id)
SendNotify('Du sitzt nun auf dem Platz: ' .. data.title, 'success')
else
SendNotify('Das Fahrzeug ist zu schnell..', 'error')
end
else
SendNotify('Dieser Platz ist belegt..', 'error')
end
-- else
-- SendNotify('Du hast einen Renngurt an und kannst dich nicht umsetzen.', 'error')
-- end
end)
RegisterNetEvent('rlo_radialmenu:client:ChangeSeat')
AddEventHandler('rlo_radialmenu:client:ChangeSeat', function(data)
local Veh = GetVehiclePedIsIn(PlayerPedId())
local IsSeatFree = IsVehicleSeatFree(Veh, data.id)
local speed = GetEntitySpeed(Veh)
-- local HasHarnass = exports['qb-smallresources']:HasHarness()
-- if not HasHarnass then
local kmh = (speed * 3.6);
if IsSeatFree then
if kmh <= 100.0 then
SetPedIntoVehicle(PlayerPedId(), Veh, data.id)
SendNotify('Du sitzt nun auf dem Platz: ' .. data.title, 'success')
else
SendNotify('Das Fahrzeug ist zu schnell..', 'error')
end
else
SendNotify('Dieser Platz ist belegt..', 'error')
end
-- else
-- SendNotify('Du hast einen Renngurt an und kannst dich nicht umsetzen.', 'error')
-- end
end)
-- ==========================================
-- DISPATCH NOTRUF SYSTEM
-- ==========================================
-- Zentrale Dispatch Funktion
local function SendDispatch(job, title, message, blip, anonymous)
local data = exports['cd_dispatch']:GetPlayerInfo()
if not data then return end
local xPlayer = ESX.GetPlayerData()
local name = (xPlayer.firstName and xPlayer.lastName) and (xPlayer.firstName .. ' ' .. xPlayer.lastName) or 'Unbekannt'
local street = tostring(data.street or 'Unbekannt')
local finalMessage
if anonymous then
finalMessage = message .. ' bei ' .. street
else
finalMessage = message .. ' (' .. name .. ') bei ' .. street
end
TriggerServerEvent('cd_dispatch:AddNotification', {
job_table = {job},
coords = data.coords,
title = title,
message = finalMessage,
flash = 0,
unique_id = tostring(math.random(0000000, 9999999)),
blip = blip
})
if anonymous then
SendNotify('Anonymer Notruf wurde abgesetzt.', 'success')
else
SendNotify('Notruf wurde abgesetzt.', 'success')
end
end
--------------------------------------------------
-- 🚓 POLICE
--------------------------------------------------
RegisterNetEvent('rlo_dispatch:police_normal', function()
SendDispatch('police', '110 - Notruf', 'Eine Person meldet einen Vorfall', {
sprite = 487, scale = 1.5, colour = 3, flashes = true,
text = 'Notruf: Polizei', time = (5*60*1000), sound = 1,
}, false)
end)
RegisterNetEvent('rlo_dispatch:police_anon', function()
SendDispatch('police', '110 - Notruf (Anonym)', 'Eine anonyme Person meldet einen Vorfall', {
sprite = 487, scale = 1.5, colour = 3, flashes = true,
text = 'Notruf: Polizei (Anonym)', time = (5*60*1000), sound = 1,
}, true)
end)
--------------------------------------------------
-- 🚑 EMS
--------------------------------------------------
RegisterNetEvent('rlo_dispatch:ems_normal', function()
SendDispatch('ambulance', '112 - Notruf', 'Eine Person benötigt medizinische Hilfe', {
sprite = 153, scale = 1.5, colour = 1, flashes = true,
text = 'Notruf: Rettungsdienst', time = (5*60*1000), sound = 1,
}, false)
end)
RegisterNetEvent('rlo_dispatch:ems_anon', function()
SendDispatch('ambulance', '112 - Notruf (Anonym)', 'Eine anonyme Person benötigt medizinische Hilfe', {
sprite = 153, scale = 1.5, colour = 1, flashes = true,
text = 'Notruf: Rettungsdienst (Anonym)', time = (5*60*1000), sound = 1,
}, true)
end)
--------------------------------------------------
-- 🔧 MECHANIKER
--------------------------------------------------
RegisterNetEvent('rlo_dispatch:mech_normal', function()
SendDispatch('mechanic', 'Pannenhilfe - Notruf', 'Eine Person benötigt einen Mechaniker', {
sprite = 446, scale = 1.5, colour = 17, flashes = false,
text = 'Notruf: Mechaniker', time = (5*60*1000), sound = 1,
}, false)
end)
RegisterNetEvent('rlo_dispatch:mech_anon', function()
SendDispatch('mechanic', 'Pannenhilfe - Notruf (Anonym)', 'Eine anonyme Person benötigt einen Mechaniker', {
sprite = 446, scale = 1.5, colour = 17, flashes = false,
text = 'Notruf: Mechaniker (Anonym)', time = (5*60*1000), sound = 1,
}, true)
end)
function DrawText3Ds(x, y, z, text)
SetTextScale(0.35, 0.35)
SetTextFont(4)
SetTextProportional(1)
SetTextColour(255, 255, 255, 215)
SetTextEntry("STRING")
SetTextCentre(true)
AddTextComponentString(text)
SetDrawOrigin(x,y,z, 0)
DrawText(0.0, 0.0)
local factor = (string.len(text)) / 370
DrawRect(0.0, 0.0+0.0125, 0.017+ factor, 0.03, 0, 0, 0, 75)
ClearDrawOrigin()
end