333 lines
12 KiB
Lua
333 lines
12 KiB
Lua
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) |