PlayerData = {} PlayerJob = {} isLoggedIn = true QBCore = exports['qb-core']:GetCoreObject() local blips = {} -- core related AddEventHandler('onResourceStart', function(resourceName) if GetCurrentResourceName() == resourceName then isLoggedIn = true PlayerData = QBCore.Functions.GetPlayerData() PlayerJob = QBCore.Functions.GetPlayerData().job end end) RegisterNetEvent("QBCore:Client:OnPlayerLoaded", function() isLoggedIn = true PlayerData = QBCore.Functions.GetPlayerData() PlayerJob = QBCore.Functions.GetPlayerData().job end) RegisterNetEvent('QBCore:Client:OnPlayerUnload', function() PlayerData = {} isLoggedIn = false currentCallSign = "" -- currentVehicle, inVehicle, currentlyArmed, currentWeapon = nil, false, false, `WEAPON_UNARMED` -- removeHuntingZones() end) RegisterNetEvent("QBCore:Client:OnJobUpdate", function(JobInfo) PlayerData = QBCore.Functions.GetPlayerData() PlayerJob = JobInfo end) ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function _U(entry) return Locales[Config.Locale][entry] end ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- function getSpeed() return speedlimit end function getStreet() return currentStreetName end function getStreetandZone(coords) local zone = GetLabelText(GetNameOfZone(coords.x, coords.y, coords.z)) local currentStreetHash = GetStreetNameAtCoord(coords.x, coords.y, coords.z) currentStreetName = GetStreetNameFromHashKey(currentStreetHash) playerStreetsLocation = currentStreetName .. ", " .. zone return playerStreetsLocation end function refreshPlayerWhitelisted() if not PlayerData then return false end if not PlayerData.job then return false end if Config.Debug then return true end for k,v in ipairs({'police'}) do if v == PlayerData.job.name then return true end end return false end function BlacklistedWeapon(playerPed) for i = 1, #Config.WeaponBlacklist do local weaponHash = GetHashKey(Config.WeaponBlacklist[i]) if GetSelectedPedWeapon(playerPed) == weaponHash then return true -- Is a blacklisted weapon end end return false -- Is not a blacklisted weapon end function GetAllPeds() local getPeds = {} local findHandle, foundPed = FindFirstPed() local continueFind = (foundPed and true or false) local count = 0 while continueFind do local pedCoords = GetEntityCoords(foundPed) if GetPedType(foundPed) ~= 28 and not IsEntityDead(foundPed) and not IsPedAPlayer(foundPed) and #(playerCoords - pedCoords) < 80.0 then getPeds[#getPeds + 1] = foundPed count = count + 1 end continueFind, foundPed = FindNextPed(findHandle) end EndFindPed(findHandle) return count end function zoneChance(type, zoneMod, street) if Config.DebugChance then return true end if not street then street = currentStreetName end playerCoords = GetEntityCoords(PlayerPedId()) local zone, sendit = GetLabelText(GetNameOfZone(playerCoords.x, playerCoords.y, playerCoords.z)), false if not nearbyPeds then nearbyPeds = GetAllPeds() elseif nearbyPeds < 1 then if Config.Debug then print(('^1[%s] Nobody is nearby to send a report^7'):format(type)) end return false end if zoneMod == nil then zoneMod = 1 end zoneMod = (math.ceil(zoneMod+0.5)) local hour = GetClockHours() if hour >= 21 or hour <= 4 then zoneMod = zoneMod * 1.6 zoneMod = math.ceil(zoneMod+0.5) end zoneMod = zoneMod / (nearbyPeds / 3) zoneMod = (math.ceil(zoneMod+0.5)) local sum = math.random(1, zoneMod) local chance = string.format('%.2f',(1 / zoneMod) * 100)..'%' if sum > 1 then if Config.Debug then print(('^1[%s] %s (%s) - %s nearby peds^7'):format(type, zone, chance, nearbyPeds)) end sendit = false else if Config.Debug then print(('^2[%s] %s (%s) - %s nearby peds^7'):format(type, zone, chance, nearbyPeds)) end sendit = true end print(('^1[%s] %s (%s) - %s nearby peds^7'):format(type, zone, chance, nearbyPeds)) return sendit end function vehicleData(vehicle) local vData = {} local vehicleClass = GetVehicleClass(vehicle) local vClass = {[0] = _U('compact'), [1] = _U('sedan'), [2] = _U('suv'), [3] = _U('coupe'), [4] = _U('muscle'), [5] = _U('sports_classic'), [6] = _U('sports'), [7] = _U('super'), [8] = _U('motorcycle'), [9] = _U('offroad'), [10] = _U('industrial'), [11] = _U('utility'), [12] = _U('van'), [17] = _U('service'), [19] = _U('military'), [20] = _U('truck')} local vehClass = vClass[vehicleClass] local vehicleName = GetLabelText(GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))) local vehicleColour1, vehicleColour2 = GetVehicleColours(vehicle) if vehicleColour1 then if Config.Colours[tostring(vehicleColour2)] and Config.Colours[tostring(vehicleColour1)] then vehicleColour = Config.Colours[tostring(vehicleColour2)] .. " on " .. Config.Colours[tostring(vehicleColour1)] elseif Config.Colours[tostring(vehicleColour1)] then vehicleColour = Config.Colours[tostring(vehicleColour1)] elseif Config.Colours[tostring(vehicleColour2)] then vehicleColour = Config.Colours[tostring(vehicleColour2)] else vehicleColour = "Ukendt" end end local plate = GetVehicleNumberPlateText(vehicle) local doorCount = 0 if GetEntityBoneIndexByName(vehicle, 'door_pside_f') ~= -1 then doorCount = doorCount + 1 end if GetEntityBoneIndexByName(vehicle, 'door_pside_r') ~= -1 then doorCount = doorCount + 1 end if GetEntityBoneIndexByName(vehicle, 'door_dside_f') ~= -1 then doorCount = doorCount + 1 end if GetEntityBoneIndexByName(vehicle, 'door_dside_r') ~= -1 then doorCount = doorCount + 1 end if doorCount == 2 then doorCount = _U('two_door') elseif doorCount == 3 then doorCount = _U('three_door') elseif doorCount == 4 then doorCount = _U('four_door') else doorCount = '' end vData.class, vData.name, vData.colour, vData.doors, vData.plate, vData.id = vehClass, vehicleName, vehicleColour, doorCount, plate, NetworkGetNetworkIdFromEntity(vehicle) return vData end function GetPedGender() local gender = "Mand" if QBCore.Functions.GetPlayerData().charinfo.gender == 1 then gender = "Kvinde" end return gender end function getCardinalDirectionFromHeading() local heading = GetEntityHeading(PlayerPedId()) if heading >= 315 or heading < 45 then return "Nordgående" elseif heading >= 45 and heading < 135 then return "Vestgående" elseif heading >=135 and heading < 225 then return "Sydgående" elseif heading >= 225 and heading < 315 then return "Østgående" end end function IsPoliceJob(job) for k, v in pairs(Config.PoliceJob) do if job == v then return true end end return false end local function IsValidJob(jobList) for k, v in pairs(jobList) do if v == PlayerJob.name then return true end end return false end local function CheckOnDuty() if Config.OnDutyOnly then return PlayerJob.onduty end return true end -- Dispatch Itself local disableNotis, disableNotifSounds = false, false RegisterNetEvent('dispatch:manageNotifs', function(sentSetting) local wantedSetting = tostring(sentSetting) if wantedSetting == "on" then disableNotis = false disableNotifSounds = false QBCore.Functions.Notify("Dispatch slået til", "success") elseif wantedSetting == "off" then disableNotis = true disableNotifSounds = true QBCore.Functions.Notify("Dispatch slået fra", "success") elseif wantedSetting == "mute" then disableNotis = false disableNotifSounds = true QBCore.Functions.Notify("Dispatch muted", "success") else QBCore.Functions.Notify('Vælg venligt "on", "off" eller "mute", for dispatch notifikationer.', "success") end end) RegisterNetEvent('dispatch:clNotify', function(sNotificationData, sNotificationId, sender) if sNotificationData ~= nil and isLoggedIn then if IsValidJob(sNotificationData['job']) and CheckOnDuty() then if not disableNotis then if sNotificationData.origin ~= nil then SendNUIMessage({ update = "newCall", callID = sNotificationId, data = sNotificationData, timer = 5000, isPolice = IsPoliceJob(PlayerJob.name) }) end end end end end) RegisterNetEvent("ps-dispatch:client:AddCallBlip", function(coords, data, blipId) if IsValidJob(data.recipientList) and CheckOnDuty() then PlaySound(-1, data.sound, data.sound2, 0, 0, 1) TriggerServerEvent("InteractSound_SV:PlayOnSource", data.sound, 0.25) -- For Custom Sounds CreateThread(function() local alpha = 255 local blip = nil local radius = nil local radiusAlpha = 128 local sprite, colour, scale = 161, 84, 0.5 local randomoffset = math.random(1,100) if data.blipSprite then sprite = data.blipSprite end if data.blipColour then colour = data.blipColour end if data.blipScale then scale = data.blipScale end if data.radius then radius = data.radius end if data.offset == "true" then if randomoffset <= 25 then radius = AddBlipForRadius(coords.x + math.random(Config.MinOffset, Config.MaxOffset), coords.y + math.random(Config.MinOffset, Config.MaxOffset), coords.z, data.radius) blip = AddBlipForCoord(coords.x + math.random(Config.MinOffset, Config.MaxOffset), coords.y + math.random(Config.MinOffset, Config.MaxOffset), coords.z) blips[blipId] = blip elseif randomoffset >= 26 and randomoffset <= 50 then radius = AddBlipForRadius(coords.x - math.random(Config.MinOffset, Config.MaxOffset), coords.y + math.random(Config.MinOffset, Config.MaxOffset), coords.z, data.radius) blip = AddBlipForCoord(coords.x - math.random(Config.MinOffset, Config.MaxOffset), coords.y + math.random(Config.MinOffset, Config.MaxOffset), coords.z) blips[blipId] = blip elseif randomoffset >= 51 and randomoffset <= 74 then radius = AddBlipForRadius(coords.x - math.random(Config.MinOffset, Config.MaxOffset), coords.y - math.random(Config.MinOffset, Config.MaxOffset), coords.z, data.radius) blip = AddBlipForCoord(coords.x - math.random(Config.MinOffset, Config.MaxOffset), coords.y - math.random(Config.MinOffset, Config.MaxOffset), coords.z) blips[blipId] = blip elseif randomoffset >= 75 and randomoffset <= 100 then radius = AddBlipForRadius(coords.x + math.random(Config.MinOffset, Config.MaxOffset), coords.y - math.random(Config.MinOffset, Config.MaxOffset), coords.z, data.radius) blip = AddBlipForCoord(coords.x + math.random(Config.MinOffset, Config.MaxOffset), coords.y - math.random(Config.MinOffset, Config.MaxOffset), coords.z) blips[blipId] = blip end elseif data.offset == "false" then radius = AddBlipForRadius(coords.x, coords.y, coords.z, data.radius) blip = AddBlipForCoord(coords.x, coords.y, coords.z) blips[blipId] = blip end if data.blipflash == "true" then SetBlipFlashes(blip, true) elseif data.blipflash == "false" then SetBlipFlashes(blip, false) end SetBlipSprite(blip, sprite) SetBlipHighDetail(blip, true) SetBlipScale(blip, scale) SetBlipColour(blip, colour) SetBlipAlpha(blip, alpha) SetBlipAsShortRange(blip, false) SetBlipCategory(blip, 2) SetBlipColour(radius, colour) SetBlipAlpha(radius, radiusAlpha) BeginTextCommandSetBlipName('STRING') AddTextComponentString(data.displayCode..' - '..data.description) EndTextCommandSetBlipName(blip) while radiusAlpha ~= 0 do Wait(data.blipLength * 1000) radiusAlpha = radiusAlpha - 1 SetBlipAlpha(radius, radiusAlpha) if radiusAlpha == 0 then RemoveBlip(radius) RemoveBlip(blip) return end end end) end end) RegisterNetEvent('dispatch:getCallResponse', function(message) SendNUIMessage({ update = "newCall", callID = math.random(1000, 9999), data = { dispatchCode = 'RSP', priority = 1, dispatchMessage = "Opkald svar", information = message }, timer = 10000, isPolice = true }) end) RegisterNetEvent("ps-dispatch:client:Explosion", function(data) exports["ps-dispatch"]:Explosion() end) RegisterNetEvent("ps-dispatch:client:removeCallBlip", function(blipId) RemoveBlip(blips[blipId]) end) RegisterNetEvent("ps-dispatch:client:clearAllBlips", function() for k, v in pairs(blips) do RemoveBlip(v) end QBCore.Functions.Notify('Alle dispatch-blips er fjernet', "success") end)