local self = ESX.Modules['job_police'] -- Locals local Input = ESX.Modules['input'] RegisterNetEvent('esx:setJob') AddEventHandler('esx:setJob', function(job) Citizen.Wait(5000) TriggerServerEvent('esx_policejob:forceBlip') end) RegisterNetEvent('esx_phone:loaded') AddEventHandler('esx_phone:loaded', function(phoneNumber, contacts) local specialContact = { name = _U('job_police:phone_police'), number = 'police', base64Icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NDFGQTJDRkI0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NDFGQTJDRkM0QUJCMTFFN0JBNkQ5OENBMUI4QUEzM0YiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo0MUZBMkNGOTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo0MUZBMkNGQTRBQkIxMUU3QkE2RDk4Q0ExQjhBQTMzRiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PoW66EYAAAjGSURBVHjapJcLcFTV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' } TriggerEvent('esx_phone:addSpecialContact', specialContact.name, specialContact.number, specialContact.base64Icon) end) -- don't show dispatches if the player isn't in service AddEventHandler('esx_phone:cancelMessage', function(dispatchNumber) if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and ESX.PlayerData.job.name == dispatchNumber then -- if esx_service is enabled if self.Config.EnableESXService and not playerInService then CancelEvent() end end end) AddEventHandler('esx_policejob:hasEnteredMarker', function(station, part, partNum) if part == 'Cloakroom' then self.CurrentAction = 'menu_cloakroom' self.CurrentActionMsg = _U('job_police:open_cloackroom') self.CurrentActionData = {} elseif part == 'Armory' then self.CurrentAction = 'menu_armory' self.CurrentActionMsg = _U('job_police:open_armory') self.CurrentActionData = {station = station} elseif part == 'Vehicles' then self.CurrentAction = 'menu_vehicle_spawner' self.CurrentActionMsg = _U('job_police:garage_prompt') self.CurrentActionData = {station = station, part = part, partNum = partNum} elseif part == 'Helicopters' then self.CurrentAction = 'Helicopters' self.CurrentActionMsg = _U('job_police:helicopter_prompt') self.CurrentActionData = {station = station, part = part, partNum = partNum} elseif part == 'BossActions' then self.CurrentAction = 'menu_boss_actions' self.CurrentActionMsg = _U('job_police:open_bossmenu') self.CurrentActionData = {} end end) AddEventHandler('esx_policejob:hasExitedMarker', function(station, part, partNum) if not isInShopMenu then ESX.UI.Menu.CloseAll() end self.CurrentAction = nil end) AddEventHandler('esx_policejob:hasEnteredEntityZone', function(entity) local playerPed = PlayerPedId() if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' and IsPedOnFoot(playerPed) then self.CurrentAction = 'remove_entity' self.CurrentActionMsg = _U('job_police:remove_prop') self.CurrentActionData = {entity = entity} end if GetEntityModel(entity) == GetHashKey('p_ld_stinger_s') then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) if IsPedInAnyVehicle(playerPed, false) then local vehicle = GetVehiclePedIsIn(playerPed) for i=0, 7, 1 do SetVehicleTyreBurst(vehicle, i, true, 1000) end end end end) AddEventHandler('esx_policejob:hasExitedEntityZone', function(entity) if self.CurrentAction == 'remove_entity' then self.CurrentAction = nil end end) RegisterNetEvent('esx_policejob:handcuff') AddEventHandler('esx_policejob:handcuff', function() self.IsHandcuffed = not self.IsHandcuffed local playerPed = PlayerPedId() if self.IsHandcuffed then RequestAnimDict('mp_arresting') while not HasAnimDictLoaded('mp_arresting') do Citizen.Wait(100) end TaskPlayAnim(playerPed, 'mp_arresting', 'idle', 8.0, -8, -1, 49, 0, 0, 0, 0) SetEnableHandcuffs(playerPed, true) DisablePlayerFiring(playerPed, true) SetCurrentPedWeapon(playerPed, GetHashKey('WEAPON_UNARMED'), true) -- unarm player SetPedCanPlayGestureAnims(playerPed, false) FreezeEntityPosition(playerPed, true) DisplayRadar(false) if self.Config.EnableHandcuffTimer then if handcuffTimer.active then ESX.ClearTimeout(handcuffTimer.task) end StartHandcuffTimer() end else if self.Config.EnableHandcuffTimer and handcuffTimer.active then ESX.ClearTimeout(handcuffTimer.task) end ClearPedSecondaryTask(playerPed) SetEnableHandcuffs(playerPed, false) DisablePlayerFiring(playerPed, false) SetPedCanPlayGestureAnims(playerPed, true) FreezeEntityPosition(playerPed, false) DisplayRadar(true) end end) RegisterNetEvent('esx_policejob:unrestrain') AddEventHandler('esx_policejob:unrestrain', function() if self.IsHandcuffed then local playerPed = PlayerPedId() self.IsHandcuffed = false ClearPedSecondaryTask(playerPed) SetEnableHandcuffs(playerPed, false) DisablePlayerFiring(playerPed, false) SetPedCanPlayGestureAnims(playerPed, true) FreezeEntityPosition(playerPed, false) DisplayRadar(true) -- end timer if self.Config.EnableHandcuffTimer and handcuffTimer.active then ESX.ClearTimeout(handcuffTimer.task) end end end) RegisterNetEvent('esx_policejob:drag') AddEventHandler('esx_policejob:drag', function(copId) if self.IsHandcuffed then dragStatus.isDragged = not dragStatus.isDragged dragStatus.CopId = copId end end) RegisterNetEvent('esx_policejob:putInVehicle') AddEventHandler('esx_policejob:putInVehicle', function() if self.IsHandcuffed then local playerPed = PlayerPedId() local coords = GetEntityCoords(playerPed) if IsAnyVehicleNearPoint(coords, 5.0) then local vehicle = GetClosestVehicle(coords, 5.0, 0, 71) if DoesEntityExist(vehicle) then local maxSeats, freeSeat = GetVehicleMaxNumberOfPassengers(vehicle) for i=maxSeats - 1, 0, -1 do if IsVehicleSeatFree(vehicle, i) then freeSeat = i break end end if freeSeat then TaskWarpPedIntoVehicle(playerPed, vehicle, freeSeat) dragStatus.isDragged = false end end end end end) RegisterNetEvent('esx_policejob:OutVehicle') AddEventHandler('esx_policejob:OutVehicle', function() local playerPed = PlayerPedId() if IsPedSittingInAnyVehicle(playerPed) then local vehicle = GetVehiclePedIsIn(playerPed, false) TaskLeaveVehicle(playerPed, vehicle, 16) end end) RegisterNetEvent('esx_policejob:updateBlip') AddEventHandler('esx_policejob:updateBlip', function() -- Refresh all blips for k, existingBlip in pairs(self.BlipsCops) do RemoveBlip(existingBlip) end -- Clean the blip table self.BlipsCops = {} -- Enable blip? if self.Config.EnableESXService and not playerInService then return end if not self.Config.EnableJobBlip then return end -- Is the player a cop? In that case show all the blips for other cops if ESX.PlayerData.job and ESX.PlayerData.job.name == 'police' then ESX.TriggerServerCallback('esx_society:getOnlinePlayers', function(players) for i=1, #players, 1 do if players[i].job.name == 'police' then local id = GetPlayerFromServerId(players[i].source) if NetworkIsPlayerActive(id) and GetPlayerPed(id) ~= PlayerPedId() then CreateBlip(id) end end end end) end end) AddEventHandler('playerSpawned', function(spawn) isDead = false TriggerEvent('esx_policejob:unrestrain') if not hasAlreadyJoined then TriggerServerEvent('esx_policejob:spawned') end hasAlreadyJoined = true end) AddEventHandler('esx:onPlayerDeath', function(data) isDead = true end) AddEventHandler('onResourceStop', function(resource) if resource == GetCurrentResourceName() then TriggerEvent('esx_policejob:unrestrain') TriggerEvent('esx_phone:removeSpecialContact', 'police') if self.Config.EnableESXService then TriggerServerEvent('esx_service:disableService', 'police') end if self.Config.EnableHandcuffTimer and self.HandcuffTimer.active then ESX.ClearTimeout(self.HandcuffTimer.task) end end end) -- Key Controls Input.On('released', Input.Groups.MOVE, Input.Controls.PICKUP, function(lastPressed) if self.CurrentAction and self.IsPolice() then self.CurrentAction() self.CurrentAction = nil end end) Input.On('released', Input.Groups.MOVE, Input.Controls.SELECT_CHARACTER_FRANKLIN, function(lastPressed) if (not self.IsDead) and self.IsPolice() and (not ESX.UI.Menu.IsOpen('default', GetCurrentResourceName(), 'police_actions')) then if not self.Config.EnableESXService then OpenPoliceActionsMenu() elseif playerInService then OpenPoliceActionsMenu() else ESX.ShowNotification(_U('job_police:service_not')) end end end) Input.On('released', Input.Groups.MOVE, Input.Controls.PICKUP, function(lastPressed) if self.CurrentAction and self.IsPolice() and self.CurrentTask.busy then ESX.ShowNotification(_U('job_police:impound_canceled')) ESX.ClearTimeout(self.CurrentTask.task) ClearPedTasks(PlayerPedId()) self.CurrentTask.busy = false end end)